# [vtkusers] Close the gap between a mesh and a planar

Jacky Nguyen jackynguyen.km at gmail.com
Thu Jul 19 01:43:37 EDT 2018

```Ahh I see, thank you very much for the explanation!

Best Regards,

Jacky

On Thu, Jul 19, 2018 at 12:10 PM kenichiro yoshimi <rccm.kyoshimi at gmail.com>
wrote:

> Hi,
>
> The second half of numbers of points indicates the target side of
> extrusion, while the first half is the source side. Here, only the
> target side must be projected on x-y plane.
>
> Thanks
> 2018年7月19日(木) 12:23 Jacky Nguyen <jackynguyen.km at gmail.com>:
> >
> > Also, can you please explain why populating the points must be from half
> the number of points onward but not from 0 ? I am referring to this line:
> >
> > for ptId in range(round(numPts/2), numPts):
> >
> >
> >
> > Thank you,
> >
> > Jacky
> >
> > On Thu, Jul 19, 2018 at 9:13 AM Jacky Nguyen <jackynguyen.km at gmail.com>
> wrote:
> >>
> >> Hi Kenichiro,
> >>
> >> Your method works! I am new to 3D stuff so i was not aware of this
> vtkLinearExtrusionFilter. But I did hear of this term when I worked with
> the 3D modelling guy when he said he manually did extrude the original
> shape.
> >>
> >> Thank you for your help!
> >>
> >> Jacky
> >>
> >> On Wed, Jul 18, 2018 at 8:34 PM kenichiro yoshimi <
> rccm.kyoshimi at gmail.com> wrote:
> >>>
> >>> Hi,
> >>>
> >>> Excuse me for cutting in. I am inspired by Patrick method.
> >>> First create a skirt from boundary edges of polygonal data by
> >>> vtkLinearExtrusionFilter
> >>> and then place the extruded points at x-y plane.
> >>>
> >>> ---
> >>> #!/usr/bin/env python
> >>> # -*- coding: utf-8 -*-
> >>>
> >>> import vtk
> >>>
> >>>
> >>> def main():
> >>>     colors = vtk.vtkNamedColors()
> >>>
> >>>
> >>>     # Apply linear extrusion
> >>>     extrude = vtk.vtkLinearExtrusionFilter()
> >>>     extrude.SetExtrusionTypeToNormalExtrusion();
> >>>     extrude.SetVector(0, 0, -10)
> >>>     extrude.CappingOn()
> >>>     extrude.Update()
> >>>
> >>>     # project extruded points onto x-y plane
> >>>     z = 1130
> >>>     closedSurface = extrude.GetOutput()
> >>>     points = closedSurface.GetPoints()
> >>>     numPts = closedSurface.GetNumberOfPoints()
> >>>     for ptId in range(numPts/2, numPts):
> >>>       point = points.GetPoint(ptId)
> >>>       points.SetPoint(ptId, point[0], point[1], z)
> >>>
> >>>     # Create a mapper and actor.
> >>>     mapper = vtk.vtkPolyDataMapper()
> >>>     mapper.SetInputData(closedSurface)
> >>>
> >>>     actor = vtk.vtkActor()
> >>>     actor.GetProperty().SetColor(colors.GetColor3d("Cornsilk"))
> >>>     actor.SetMapper(mapper)
> >>>
> >>>     # Create a renderer, render window, and interactor
> >>>     renderer = vtk.vtkRenderer()
> >>>     renderWindow = vtk.vtkRenderWindow()
> >>>     renderWindow.SetWindowName("TaperedCylinder")
> >>>     renderWindowInteractor = vtk.vtkRenderWindowInteractor()
> >>>     renderWindowInteractor.SetRenderWindow(renderWindow)
> >>>
> >>>     # Add the actors to the scene
> >>>     renderer.SetBackground(colors.GetColor3d("DarkGreen"))
> >>>
> >>>     # Render and interact
> >>>     renderWindow.Render()
> >>>     renderWindowInteractor.Start()
> >>>
> >>>
> >>> if __name__ == '__main__':
> >>>     main()
> >>> ---
> >>>
> >>> 2018年7月18日(水) 15:44 Jacky Nguyen <jackynguyen.km at gmail.com>:
> >>> >
> >>> > Hi Patrick,
> >>> >
> >>> > Thanks for the clarification. I have tried your approach, but
> however the wall was not covered up the entire boundary. The wall was
> stopped kinda half way.
> >>> > Do you mind taking a look at my code to see what went wrong? I have
> created a gist here:
> https://gist.github.com/ngunhaSO/f3902fd34172a161b678b2a05a5c91fe
> >>> > I have also attached a stl file that i wanna manipulate and the
> screenshot of what i achieved here: https://github.com/ngunhaSO/misc
> >>> >
> >>> > Thank you!
> >>> >
> >>> > Jacky
> >>> >
> >>> > On Mon, Jul 16, 2018 at 7:48 PM Patrick Bergeron <
> pbergeron at spiria.com> wrote:
> >>> >>
> >>> >> Hi Jacky
> >>> >>
> >>> >>
> >>> >>
> >>> >> Let me try to be clearer. Let’s say you have a surface floating in
> space, which seems to be your case.
> >>> >>
> >>> >>
> >>> >>
> >>> >> You can create a wall around your surface, by creating new geometry
> around your surface, which we will say is your wall. On the wall, you need
> to connect boundary edges with the floor (at z=0).
> >>> >>
> >>> >>
> >>> >>
> >>> >> So set’s say you find a boundary edge with points a and b
> >>> >>
> >>> >>
> >>> >>
> >>> >> Add 2 points to your polydata. (xa, ya, 0),  (xb, yb, 0)
> >>> >>
> >>> >>
> >>> >>
> >>> >> Then you create a quad that goes like this:
> >>> >>
> >>> >>
> >>> >>
> >>> >> (xa,ya,za),
> >>> >>
> >>> >>  (xb,yb,zb)
> >>> >>
> >>> >> (xb,yb,0)
> >>> >>
> >>> >> (xa,ya,0)
> >>> >>
> >>> >>
> >>> >>
> >>> >> Or if you prefer you can create 2 triangles:
> >>> >>
> >>> >> (xa,ya,za),
> >>> >>
> >>> >>  (xb,yb,zb)
> >>> >>
> >>> >> (xb,yb,0)
> >>> >>
> >>> >>
> >>> >>
> >>> >> (xb,yb,0)
> >>> >>
> >>> >> (xa,ya,0)
> >>> >>
> >>> >> (xa,ya,za),
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >> Anyway, after you create your walls at each boundary edge, you end
> up with walls that go all around your surface, but with no horizontal
> surface  at the bottom. Maybe this is important to you, maybe not.
> >>> >>
> >>> >>
> >>> >>
> >>> >> If it’s important, you can create a duplicate copy of your top
> surface, but in the copy, set all your point’s  Z to 0.0.
> >>> >>
> >>> >>
> >>> >>
> >>> >> This will flatten out the copy of your top surface and place it at
> Z=0, connecting to the bottom of your wall that you created all around your
> surface
> >>> >>
> >>> >>
> >>> >>
> >>> >> You will end up with a volume with the sides and bottom capped off.
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >> Patrick.
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >> From: Jacky Nguyen <jackynguyen.km at gmail.com>
> >>> >> Date: Monday, July 16, 2018 at 5:12 AM
> >>> >> To: Patrick Bergeron <pbergeron at spiria.com>
> >>> >> Cc: "vtkusers at public.kitware.com" <vtkusers at public.kitware.com>
> >>> >> Subject: Re: [vtkusers] Close the gap between a mesh and a planar
> >>> >>
> >>> >>
> >>> >>
> >>> >> Thanks for your input.
> >>> >>
> >>> >> Sorry, I am new to these so I need to take it slowly.
> >>> >>
> >>> >>
> >>> >>
> >>> >> Let me clarify a few things:
> >>> >>
> >>> >> 1) by using your approach, i don't need to create the plane on the
> bottom of the object as a holder?
> >>> >>
> >>> >> 2) When you say "For each boundary edge, create 2 triangles (a
> quad) with 1 or 2 points at z=0", does it matter which x and y coordinate
> to pick?
> >>> >>
> >>> >>
> >>> >>
> >>> >> I have added the following codes to extract the edges and find the
> pointID and point coordinate for each edge in the STL object. I trace
> through my console log, and there is no point that has z = 0
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >> triangleFilter = vtk.vtkTriangleFilter()
> >>> >> triangleFilter.Update()
> >>> >>
> >>> >> # ++++++++++++++++++ extract edges
> ++++++++++++++++++++++++++++++++++++
> >>> >>
> >>> >> featureEdges = vtk.vtkFeatureEdges()
> >>> >> featureEdges.SetInputData(triangleFilter.GetOutput())
> >>> >> featureEdges.SetBoundaryEdges(1)
> >>> >> featureEdges.SetFeatureEdges(0)
> >>> >> featureEdges.SetNonManifoldEdges(0)
> >>> >> featureEdges.SetManifoldEdges(0)
> >>> >> featureEdges.Update()
> >>> >> boundaryMesh = featureEdges.GetOutput()
> >>> >> numberOfOpenEdges = featureEdges.GetOutput().GetNumberOfLines()
> >>> >> print('number of lines: ',
> featureEdges.GetOutput().GetNumberOfLines())
> >>> >> for i in range(0, boundaryMesh.GetNumberOfLines()):
> >>> >>     cell = boundaryMesh.GetCell(i)
> >>> >>     cellPoints = cell.GetPoints()
> >>> >>     pointIds = cell.GetPointIds()
> >>> >>     for j in range(0, pointIds.GetNumberOfIds()):
> >>> >>         print('>>> point id: ', pointIds.GetId(j))
> >>> >>         print('>>> coordinate: ',
> boundaryMesh.GetPoint(pointIds.GetId(j)))
> >>> >>
> >>> >>
> >>> >>
> >>> >> Thank you,
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >> On Fri, Jul 13, 2018 at 10:10 PM Patrick Bergeron <
> pbergeron at spiria.com> wrote:
> >>> >>
> >>> >> I would take a different approach.
> >>> >>
> >>> >>
> >>> >>
> >>> >> I would look at all the edges that have only 1 cell attached, and
> these are your boundary edges.
> >>> >>
> >>> >>
> >>> >>
> >>> >> For each boundary edge, create 2 triangles (a quad) with 1 or 2
> points at z=0. (Create 2 new points at z=0 for this purpose). If you
> already have a point at that z=0, then reuse it don’t create it.
> >>> >>
> >>> >>
> >>> >>
> >>> >> That approach will create quads all around your geometry connecting
> to the bottom but will leave the bottom hole open.
> >>> >>
> >>> >>
> >>> >>
> >>> >> Next create a cell connecting all your z=0 points together. Make
> sure they are ordered in sequential order to create your contour loop.
> >>> >>
> >>> >>
> >>> >>
> >>> >> Done
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >> Sent from my iPhone
> >>> >>
> >>> >>
> >>> >> On Jul 13, 2018, at 05:10, Jacky Nguyen <jackynguyen.km at gmail.com>
> wrote:
> >>> >>
> >>> >> I have converted an .obj mesh file to .stl. I also created a planar
> geometry as a holder for the mesh object then merge them. However, it
> contains a gap. Any suggestion how to close the gap vertically so that it
> becomes a solid object, I have already tried vtkFillHolesFilter, but it
> won't fill the gap?
> >>> >>
> >>> >>
> >>> >>
> >>> >> The code to create the planar:
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >> #create a grid
> >>> >>
> >>> >> xCoords = vtk.vtkFloatArray()
> >>> >>
> >>> >> for x, i in enumerate(np.linspace(xmin, xmax,50)):
> >>> >>
> >>> >>     xCoords.InsertNextValue(i)
> >>> >>
> >>> >>
> >>> >>
> >>> >> yCoords = vtk.vtkFloatArray()
> >>> >>
> >>> >> for y, i in enumerate(np.linspace(ymin, ymax, 50)):
> >>> >>
> >>> >>     yCoords.InsertNextValue(i)
> >>> >>
> >>> >>
> >>> >>
> >>> >> zCoords = vtk.vtkFloatArray()
> >>> >>
> >>> >> for z, i in enumerate(np.linspace(zmin, zmin + 1, 50)):
> >>> >>
> >>> >>     zCoords.InsertNextValue(i)
> >>> >>
> >>> >>
> >>> >>
> >>> >> rgrid = vtk.vtkRectilinearGrid()
> >>> >>
> >>> >> rgrid.SetDimensions(x + 1, y + 1 , z + 1)
> >>> >>
> >>> >> rgrid.SetXCoordinates(xCoords)
> >>> >>
> >>> >> rgrid.SetYCoordinates(yCoords)
> >>> >>
> >>> >> rgrid.SetZCoordinates(zCoords)
> >>> >>
> >>> >> signedDistances = vtk.vtkFloatArray()
> >>> >>
> >>> >> signedDistances.SetNumberOfComponents(1)
> >>> >>
> >>> >> signedDistances.SetName("SignedDistances")
> >>> >>
> >>> >>
> >>> >>
> >>> >> # Evaluate the signed distance function at all of the grid points
> >>> >>
> >>> >> for pointId in range(rgrid.GetNumberOfPoints()):
> >>> >>
> >>> >>     p = rgrid.GetPoint(pointId)
> >>> >>
> >>> >>     signedDistance = implicitPolyDataDistance.EvaluateFunction(p)
> >>> >>
> >>> >>     signedDistances.InsertNextValue(signedDistance)
> >>> >>
> >>> >>
> >>> >>
> >>> >> # add the SignedDistances to the grid
> >>> >>
> >>> >> rgrid.GetPointData().SetScalars(signedDistances)
> >>> >>
> >>> >>
> >>> >>
> >>> >> # geometry filter to view the background grid
> >>> >>
> >>> >> geometryFilter = vtk.vtkRectilinearGridGeometryFilter()
> >>> >>
> >>> >> geometryFilter.SetInputData(rgrid)
> >>> >>
> >>> >> geometryFilter.SetExtent(0, x + 1, 0, y + 1, (z + 1) // 2, (z + 1)
> // 2)
> >>> >>
> >>> >> geometryFilter.Update()
> >>> >>
> >>> >> # ================ END creating a plane =======================
> >>> >>
> >>> >>
> >>> >>
> >>> >> The code that merge the stl poly data and the plane:
> >>> >>
> >>> >> meshAppend = vtk.vtkAppendPolyData()
> >>> >>
> >>> >>
> >>> >>
> >>> >> meshAppend.Update()
> >>> >>
> >>> >> boundaryClean = vtk.vtkCleanPolyData()
> >>> >>
> >>> >> boundaryClean.SetInputData(meshAppend.GetOutput())
> >>> >>
> >>> >> boundaryClean.Update()
> >>> >>
> >>> >> out = vtk.vtkPolyData()
> >>> >>
> >>> >> out.DeepCopy(boundaryClean.GetOutput())
> >>> >>
> >>> >>
> >>> >>
> >>> >> triangleTrans = vtk.vtkTriangleFilter()
> >>> >>
> >>> >> triangleTrans.SetInputData(out)
> >>> >>
> >>> >> triangleTrans.Update()
> >>> >>
> >>> >>
> >>> >>
> >>> >> fill = vtk.vtkFillHolesFilter()
> >>> >>
> >>> >> fill.SetInputData(out)
> >>> >>
> >>> >> fill.SetHoleSize(1000000.0)
> >>> >>
> >>> >> fill.Update()
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >>
> >>> >> A screenshot of what my current mesh is (note: the red line is
> where i want to close the gap vertically along the z axis:
> https://i.stack.imgur.com/F9w3c.png
> >>> >>
> >>> >>
> >>> >>
> >>> >> Any suggestion to solve this problem?
> >>> >>
> >>> >>
> >>> >>
> >>> >> Thank you
> >>> >>
> >>> >>
> >>> >>
> >>> >> _______________________________________________
> >>> >>
> >>> >> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
> >>> >>
> >>> >> Please keep messages on-topic and check the VTK FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
> >>> >>
> >>> >> Search the list archives at: http://markmail.org/search/?q=vtkusers
> >>> >>
> >>> >> https://public.kitware.com/mailman/listinfo/vtkusers
> >>> >
> >>> > _______________________________________________
> >>> >
> >>> > Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
> >>> >
> >>> > Please keep messages on-topic and check the VTK FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
> >>> >
> >>> > Search the list archives at: http://markmail.org/search/?q=vtkusers
> >>> >