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

Jacky Nguyen jackynguyen.km at gmail.com
Wed Jul 18 21:13:43 EDT 2018


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()
>
>     reader = vtk.vtkSTLReader()
>     reader.SetFileName('improve.stl')
>     reader.Update()
>
>     # Apply linear extrusion
>     extrude = vtk.vtkLinearExtrusionFilter()
>     extrude.SetInputConnection(reader.GetOutputPort())
>     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")
>     renderWindow.AddRenderer(renderer)
>     renderWindowInteractor = vtk.vtkRenderWindowInteractor()
>     renderWindowInteractor.SetRenderWindow(renderWindow)
>
>     # Add the actors to the scene
>     renderer.AddActor(actor)
>     renderer.SetBackground(colors.GetColor3d("DarkGreen"))
>
>     # Render and interact
>     renderWindow.Render()
>     renderWindowInteractor.Start()
>
>
> if __name__ == '__main__':
>     main()
> ---
>
> For your reference.
> 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
> >>
> >>
> >>
> >> reader = vtk.vtkSTLReader()
> >> reader.SetFileName('path_to_stl')
> >> reader.Update()
> >>
> >> triangleFilter = vtk.vtkTriangleFilter()
> >> triangleFilter.SetInputConnection(reader.GetOutputPort())
> >> 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:
> >>
> >>
> >>
> >> implicitPolyDataDistance = vtk.vtkImplicitPolyDataDistance()
> >>
> >> implicitPolyDataDistance.SetInput(stl_poly_data)
> >>
> >>
> >>
> >> #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.AddInputData(stl_poly_data)
> >>
> >> meshAppend.AddInputData(geometryFilter.GetOutput())
> >>
> >> 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
> >>
> >>
> >>
> >> _______________________________________________
> >> Powered by www.kitware.com
> >>
> >> 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
> >>
> >> Follow this link to subscribe/unsubscribe:
> >> https://public.kitware.com/mailman/listinfo/vtkusers
> >
> > _______________________________________________
> > Powered by www.kitware.com
> >
> > 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
> >
> > Follow this link to subscribe/unsubscribe:
> > https://public.kitware.com/mailman/listinfo/vtkusers
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20180719/4fbbba9f/attachment.html>


More information about the vtkusers mailing list