[vtkusers] Problem with vtkContourTriangulator and vtkPlaneCutter

Andrew Maclean andrew.amaclean at gmail.com
Tue Mar 6 17:20:13 EST 2018


The fact you changed the resolution and got the same issues means it is not
related to something in the vtkParametric classes.

BTW I'm getting no crashes in Linux.

Regards
   Andrew

On Wed, Mar 7, 2018 at 4:00 AM, Jeffery Lewis <jlewis at accuray.com> wrote:

> Thank you Andrew for looking into this.
>
> Doing the changes does seem to work. Unfortunately, if you change the
> resolution of the surface model by adding the following two lines of code...
>
> source->SetPhiResolution(100);
> source->SetThetaResolution(100);
>
> ...you will see the same type of issues on the filled contour.
>
> Also, if I substitute the vtkPlaneCutter for the vtkCutter using the
> vtkSuperquadricSource, it crashes in a similar way.
>
>
> Message: 11
> Date: Tue, 6 Mar 2018 15:24:06 +1100
> From: Andrew Maclean <andrew.amaclean at gmail.com>
> To: vtk <vtkusers at vtk.org>
> Cc: Jeffery Lewis <jlewis at accuray.com>
> Subject: Re: [vtkusers] Problem with vtkContourTriangulator and
> vtkPlaneCutter (Jeffery Lewis)
> Message-ID:
> <CAHDsG9Ny9mCJsY4BCetcYowhQdPftzVhPcdspXCSW8nwdyvVhA at mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> Jeffery
>
> ?I think this is related to the ParametricFunctions. These functions are
> generated by mapping R? -> R? and are then triangulated.
> I tried vtkParametricSuperToroid and sometimes the contouring and cutting
> worked but in some orientations the triangulation failed.
>
> ?If you use a vtkSuperquadricSource e.g:
> vtkSmartPointer<vtkSuperquadricSource> source =
> vtkSmartPointer<vtkSuperquadricSource>::New();
> source->SetCenter(0, 0, 0);
> source->SetPhiRoundness(1.0);
> source->SetThetaRoundness(1.0);
> source->ToroidalOn();
>
> Everything seems to work Ok.
>
> Andrew
>
>
> > ---------- Forwarded message ----------
> > From: Jeffery Lewis <jlewis at accuray.com>
> > To: "vtkusers at vtk.org" <vtkusers at vtk.org>
> > Cc:
> > Bcc:
> > Date: Fri, 2 Mar 2018 23:46:09 +0000
> > Subject: Re: [vtkusers] Problem with vtkContourTriangulator and
> > vtkPlaneCutter (Jeffery Lewis)
> > Seems like the attachments didn't go through. Here is the code.
> >
> > #include <vtkSmartPointer.h>
> > #include <vtkParametricSuperToroid.h>
> > #include <vtkParametricFunctionSource.h>
> > #include <vtkSphereSource.h>
> > #include <vtkCamera.h>
> > #include <vtkPolyDataMapper.h>
> > #include <vtkPolyDataMapper2D.h>
> > #include <vtkDataSetMapper.h>
> > #include <vtkCompositePolyDataMapper.h>
> > #include <vtkActor.h>
> > #include <vtkActor2D.h>
> > #include <vtkPlane.h>
> > #include <vtkCutter.h>
> > #include <vtkPlaneCutter.h>
> > #include <vtkProperty.h>
> > #include <vtkProperty2D.h>
> > #include <vtkRenderWindow.h>
> > #include <vtkRenderer.h>
> > #include <vtkRenderWindowInteractor.h>
> > #include <vtkMath.h>
> > #include <vtkInteractorStyle.h>
> > #include <vtkInteractorStyleImage.h>
> > #include <vtkTransform.h>
> > #include <vtkContourTriangulator.h>
> > #include <vtkCleanPolyData.h>
> > #include <vtkConeSource.h>
> > #include <vtkCommand.h>
> > #include <vtkSliderWidget.h>
> > #include <vtkSliderRepresentation2D.h>
> >
> > // Callbacks for the interactions
> > class SliderCallbackN1 : public vtkCommand {
> > public:
> > static SliderCallbackN1 *New() {
> > return new SliderCallbackN1;
> > }
> > virtual void Execute(vtkObject *caller, unsigned long, void*) {
> > vtkSliderWidget *sliderWidget =
> > reinterpret_cast<vtkSliderWidget*>(caller);
> > double value = static_cast<vtkSliderRepresentation2D *>(sliderWidget->
> > GetRepresentation())->GetValue();
> > this->SuperToroid->SetN1(value);
> > }
> > SliderCallbackN1() :SuperToroid(0) {}
> > vtkParametricSuperToroid *SuperToroid;
> > };
> >
> > class SliderCallbackN2 : public vtkCommand {
> > public:
> > static SliderCallbackN2 *New() {
> > return new SliderCallbackN2;
> > }
> > virtual void Execute(vtkObject *caller, unsigned long, void*) {
> > vtkSliderWidget *sliderWidget =
> > reinterpret_cast<vtkSliderWidget*>(caller);
> > double value = static_cast<vtkSliderRepresentation2D *>(sliderWidget->
> > GetRepresentation())->GetValue();
> > this->SuperToroid->SetN2(value);
> > }
> > SliderCallbackN2() :SuperToroid(0) {}
> > vtkParametricSuperToroid *SuperToroid;
> > };
> >
> > /**This callback will rotate the surface model about x and y axis
> > depending on the
> > *current location of the mouse. This will in turn update the cut plane
> > that is ment to
> > *be normal to the camera and cuts through the middle of the model,
> showing
> > a red
> > *cut contour, and green filled contour. */
> > class InteractionCallback : public vtkCommand {
> > public:
> > static InteractionCallback* New() {
> > return new InteractionCallback;
> > }
> >
> > virtual void Execute(vtkObject*, unsigned long eventID, void* pCallData)
> > VTK_OVERRIDE {
> > if (eventID == vtkCommand::MouseMoveEvent) {
> > // Get the current mouse position.
> > int aiCurrentPosition[2];
> > m_pInteractor->GetEventPosition(aiCurrentPosition);
> >
> > // Get the view port size.
> > int iViewPortWidth = m_pInteractor->GetRenderWindow()->GetSize()[0];
> > int iViewPortHeight = m_pInteractor->GetRenderWindow()->GetSize()[1];
> >
> > // Compute rotations about x and y axis.
> > int iMousePositionAboutCenterX = aiCurrentPosition[0] -
> iViewPortWidth/2.0;
> > int iMousePositionAboutCenterY = aiCurrentPosition[1] -
> > iViewPortHeight/2.0;
> > double dRotationAboutX = -iMousePositionAboutCenterY/(
> > iViewPortHeight/2.0)*180.0;
> > double dRotationAboutY = iMousePositionAboutCenterX/(
> > iViewPortWidth/2.0)*180.0;
> >
> > // Compute transform.
> > vtkSmartPointer<vtkTransform> sptmSurfacModel =
> > vtkSmartPointer<vtkTransform>::New();
> > sptmSurfacModel->RotateX(dRotationAboutX);
> > sptmSurfacModel->RotateY(dRotationAboutY);
> >
> > // Apply the rotation to the surface model actor.
> > m_pActorSurface->SetUserMatrix(sptmSurfacModel->GetMatrix());
> >
> > // Apply the change to the cut plan normal vector.
> > // Translations are not required to be removed from the matrix since
> there
> > should be none.
> > double adInitialVector[3];
> > adInitialVector[0] = 0.0;
> > adInitialVector[1] = 0.0;
> > adInitialVector[2] = 1.0;
> > double adTransformedVector[3];
> > sptmSurfacModel->TransformPoint(adInitialVector, adTransformedVector);
> > m_pCutPlane->SetNormal(adTransformedVector[0], adTransformedVector[1],
> > adTransformedVector[2]);
> >
> > // Apply the rotation to the contour actor in the opposite direction to
> > make normal to camera.
> > sptmSurfacModel->Inverse();
> > m_pActorContour->SetUserMatrix(sptmSurfacModel->GetMatrix());
> >
> > // Apply the rotation to the filled actor in the opposite direction to
> > make normal to camera.
> > m_pActorFilled->SetUserMatrix(sptmSurfacModel->GetMatrix());
> >
> > m_pInteractor->Render();
> > }
> > }
> >
> > // Member variables
> > // ----------------
> > vtkRenderWindowInteractor* m_pInteractor;
> > vtkActor* m_pActorSurface;
> > vtkPlane* m_pCutPlane;
> > vtkActor* m_pActorContour;
> > vtkActor* m_pActorFilled;
> > };
> >
> >
> > int main(int, char *[]) {
> >
> > vtkSmartPointer<vtkParametricSuperToroid> surface =vtkSmartPointer<
> > vtkParametricSuperToroid>::New();
> > vtkSmartPointer<vtkParametricFunctionSource> source = vtkSmartPointer<
> > vtkParametricFunctionSource>::New();
> > source->SetParametricFunction(surface);
> >
> > // Create a synthetic cone.
> > /*// Un-commented out so can switch surface model source.
> > vtkSmartPointer<vtkConeSource> source = vtkSmartPointer<vtkConeSource>
> > ::New();
> > source->SetCenter(0, 0, 0);
> > source->SetRadius(1);
> > source->SetHeight(2);
> > source->SetResolution(30);
> > source->Update();
> > */
> >
> > vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>:
> > :New();
> > vtkSmartPointer<vtkPolyDataMapper> mapper =vtkSmartPointer<
> > vtkPolyDataMapper>::New();
> > vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
> >
> > mapper->SetInputConnection(source->GetOutputPort());
> >
> > vtkSmartPointer<vtkProperty> backProperty =
> vtkSmartPointer<vtkProperty>::
> > New();
> > backProperty->SetColor(0.8, 0.8, 0.8);
> > backProperty->SetOpacity(0.6);
> > actor->SetMapper(mapper);
> > actor->SetBackfaceProperty(backProperty);
> > actor->GetProperty()->SetDiffuseColor(1, 1, 1);
> > actor->GetProperty()->SetOpacity(0.6);
> >
> > vtkSmartPointer<vtkRenderWindow> renderWindow =vtkSmartPointer<
> > vtkRenderWindow>::New();
> > renderWindow->AddRenderer(renderer);
> > renderWindow->SetSize(640, 480);
> > renderer->AddActor(actor);
> > renderer->SetBackground(.2, .3, .4);
> >
> > vtkSmartPointer<vtkRenderWindowInteractor> interactor =vtkSmartPointer<
> > vtkRenderWindowInteractor>::New();
> > interactor->SetRenderWindow(renderWindow);
> >
> > // Setup a slider widget for each varying parameter BEGIN
> > double tubeWidth(.004);
> > double sliderLength(.004);
> > double titleHeight(.02);
> > double labelHeight(.02);
> >
> > vtkSmartPointer<vtkSliderRepresentation2D> sliderRepN1 =
> vtkSmartPointer<
> > vtkSliderRepresentation2D>::New();
> >
> > sliderRepN1->SetMinimumValue(0.0);
> > sliderRepN1->SetMaximumValue(4.0);
> > sliderRepN1->SetValue(1.0);
> > sliderRepN1->SetTitleText("Z squareness");
> >
> > sliderRepN1->GetPoint1Coordinate()->SetCoordinateSystemToNormalize
> > dDisplay();
> > sliderRepN1->GetPoint1Coordinate()->SetValue(.1, .1);
> > sliderRepN1->GetPoint2Coordinate()->SetCoordinateSystemToNormalize
> > dDisplay();
> > sliderRepN1->GetPoint2Coordinate()->SetValue(.9, .1);
> >
> > sliderRepN1->SetTubeWidth(tubeWidth);
> > sliderRepN1->SetSliderLength(sliderLength);
> > sliderRepN1->SetTitleHeight(titleHeight);
> > sliderRepN1->SetLabelHeight(labelHeight);
> >
> > vtkSmartPointer<vtkSliderWidget> sliderWidgetN1 = vtkSmartPointer<
> > vtkSliderWidget>::New();
> > sliderWidgetN1->SetInteractor(interactor);
> > sliderWidgetN1->SetRepresentation(sliderRepN1);
> > sliderWidgetN1->SetAnimationModeToAnimate();
> > sliderWidgetN1->EnabledOn();
> >
> > vtkSmartPointer<SliderCallbackN1> callbackN1 = vtkSmartPointer<
> > SliderCallbackN1>::New();
> > callbackN1->SuperToroid = surface;
> >
> > sliderWidgetN1->AddObserver(vtkCommand::InteractionEvent, callbackN1);
> >
> > vtkSmartPointer<vtkSliderRepresentation2D> sliderRepN2 =
> vtkSmartPointer<
> > vtkSliderRepresentation2D>::New();
> >
> > sliderRepN2->SetMinimumValue(0.0001);
> > sliderRepN2->SetMaximumValue(4.0);
> > sliderRepN2->SetValue(1.0);
> > sliderRepN2->SetTitleText("XY squareness");
> >
> > sliderRepN2->GetPoint1Coordinate()->SetCoordinateSystemToNormalize
> > dDisplay();
> > sliderRepN2->GetPoint1Coordinate()->SetValue(.1, .9);
> > sliderRepN2->GetPoint2Coordinate()->SetCoordinateSystemToNormalize
> > dDisplay();
> > sliderRepN2->GetPoint2Coordinate()->SetValue(.9, .9);
> >
> > sliderRepN2->SetTubeWidth(tubeWidth);
> > sliderRepN2->SetSliderLength(sliderLength);
> > sliderRepN2->SetTitleHeight(titleHeight);
> > sliderRepN2->SetLabelHeight(labelHeight);
> >
> > vtkSmartPointer<vtkSliderWidget> sliderWidgetN2 = vtkSmartPointer<
> > vtkSliderWidget>::New();
> > sliderWidgetN2->SetInteractor(interactor);
> > sliderWidgetN2->SetRepresentation(sliderRepN2);
> > sliderWidgetN2->SetAnimationModeToAnimate();
> > sliderWidgetN2->EnabledOn();
> >
> > vtkSmartPointer<SliderCallbackN2> callbackN2 = vtkSmartPointer<
> > SliderCallbackN2>::New();
> > callbackN2->SuperToroid = surface;
> >
> > sliderWidgetN2->AddObserver(vtkCommand::InteractionEvent, callbackN2);
> >
> > vtkSmartPointer<vtkSliderRepresentation2D> sliderRepMinimumV =
> > vtkSmartPointer<vtkSliderRepresentation2D>::New();
> >
> > sliderRepN1->SetMinimumValue(.0001);
> > sliderRepMinimumV->SetMaximumValue(.9999*vtkMath::Pi());
> > sliderRepMinimumV->SetValue(.0001);
> > sliderRepMinimumV->SetTitleText("V min");
> >
> > sliderRepMinimumV->GetPoint1Coordinate()->SetCoordinateSystemToNormalize
> > dDisplay();
> > sliderRepMinimumV->GetPoint1Coordinate()->SetValue(.1, .1);
> > sliderRepMinimumV->GetPoint2Coordinate()->SetCoordinateSystemToNormalize
> > dDisplay();
> > sliderRepMinimumV->GetPoint2Coordinate()->SetValue(.1, .9);
> >
> > sliderRepMinimumV->SetTubeWidth(tubeWidth);
> > sliderRepMinimumV->SetSliderLength(sliderLength);
> > sliderRepMinimumV->SetTitleHeight(titleHeight);
> > sliderRepMinimumV->SetLabelHeight(labelHeight);
> >
> > surface->SetN1(1.0);
> > surface->SetN2(1.0);
> > // Setup a slider widget for each varying parameter END
> >
> > // Set up the cut plane.
> > vtkSmartPointer<vtkPlane> planeCut = vtkSmartPointer<vtkPlane>::New();
> > planeCut->SetOrigin(0.0, 0.0, 0.0);
> > planeCut->SetNormal(0.0, 0.0, 1.0);
> >
> > // Set up the cutter which will produce the contour polygons.
> > vtkSmartPointer<vtkCutter> polygonsContour = vtkSmartPointer<vtkCutter>::
> > New();
> > //vtkSmartPointer<vtkPlaneCutter> polygonsContour = vtkSmartPointer<
> vtkPlaneCutter>::New();
> > // testjal
> > polygonsContour->SetInputConnection(source->GetOutputPort());
> > //polygonsContour->SetPlane(planeCut); // SetPlane only works with a
> > vtkPlaneCutter. // testjal
> > polygonsContour->SetCutFunction(planeCut);
> >
> > // Clean the polygons from the cutter. Note, this is an experiment to see
> > if this helps the fills. It does not
> > // seem to help.
> > vtkSmartPointer<vtkCleanPolyData> polygonsContourClean =
> vtkSmartPointer<vtkCleanPolyData>::New();
> > // testjal
> > polygonsContourClean->SetInputConnection(polygonsContour->
> GetOutputPort());
> > // testjal
> >
> > // Set up the filled polygons of the contour.
> > vtkSmartPointer<vtkContourTriangulator> polygonsFilled =
> vtkSmartPointer<
> > vtkContourTriangulator>::New();
> > polygonsFilled->SetInputConnection(polygonsContourClean->
> GetOutputPort());
> > polygonsFilled->TriangulationErrorDisplayOn(); // testjal
> >
> > // Set up the mapper of the contour.
> > vtkSmartPointer<vtkDataSetMapper> mapperContour = vtkSmartPointer<
> > vtkDataSetMapper>::New();
> > mapperContour->SetInputConnection(polygonsContourClean->
> GetOutputPort());
> > mapperContour->ScalarVisibilityOff();
> >
> > // Set up the mapper of the filled polygons of the contour
> > vtkSmartPointer<vtkDataSetMapper> mapperFilled = vtkSmartPointer<
> > vtkDataSetMapper>::New();
> > mapperFilled->SetInputConnection(polygonsFilled->GetOutputPort());
> > mapperFilled->ScalarVisibilityOff();
> >
> > // Set up the actor of the contour.
> > vtkSmartPointer<vtkActor> actorContour = vtkSmartPointer<vtkActor>::
> New();
> > actorContour->SetMapper(mapperContour);
> > actorContour->GetProperty()->SetColor(1,0,0);
> > actorContour->GetProperty()->SetLineWidth(5);
> >
> > // Set up the actor of the filled polygons of the contour.
> > vtkSmartPointer<vtkActor> actorFilled = vtkSmartPointer<vtkActor>::
> New();
> > actorFilled->SetMapper(mapperFilled);
> > actorFilled->GetProperty()->SetColor(0, 1, 0);
> >
> > // Add the contour actor.
> > renderer->AddActor(actorContour);
> >
> > // Add the filld polygons of the contour.
> > renderer->AddActor(actorFilled);
> >
> > // Set up the interaction.
> > vtkSmartPointer<InteractionCallback> callback = vtkSmartPointer<
> > InteractionCallback>::New();
> > callback->m_pInteractor = interactor.Get();
> > callback->m_pActorSurface = actor.Get();
> > callback->m_pCutPlane = planeCut.Get();
> > callback->m_pActorContour = actorContour.Get();
> > callback->m_pActorFilled = actorFilled.Get();
> > vtkSmartPointer<vtkInteractorStyle> style = vtkSmartPointer<
> > vtkInteractorStyle>::New();
> > interactor->SetInteractorStyle(style);
> > style->AddObserver(vtkCommand::MouseMoveEvent, callback);
> >
> > renderer->ResetCamera(-1, 1, -1, 1, -1, 1);
> > renderer->GetActiveCamera()->ParallelProjectionOn();
> > renderWindow->Render();
> >
> > interactor->Initialize();
> >
> > interactor->Start();
> >
> > return EXIT_SUCCESS;
> > }
> >
>
-- 
___________________________________________
Andrew J. P. Maclean

___________________________________________
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://vtk.org/pipermail/vtkusers/attachments/20180307/d62b3785/attachment.html>


More information about the vtkusers mailing list