<div dir="ltr">Hi Kenichiro,<div><br></div><div>Your method works! I am new to 3D stuff so i was not aware of this <span style="font-size:12.8px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">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.</span></div><div><br></div><div>Thank you for your help!</div><div><br></div><div>Jacky</div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Jul 18, 2018 at 8:34 PM kenichiro yoshimi <<a href="mailto:rccm.kyoshimi@gmail.com">rccm.kyoshimi@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
Excuse me for cutting in. I am inspired by Patrick method.<br>
First create a skirt from boundary edges of polygonal data by<br>
vtkLinearExtrusionFilter<br>
and then place the extruded points at x-y plane.<br>
<br>
---<br>
#!/usr/bin/env python<br>
# -*- coding: utf-8 -*-<br>
<br>
import vtk<br>
<br>
<br>
def main():<br>
    colors = vtk.vtkNamedColors()<br>
<br>
    reader = vtk.vtkSTLReader()<br>
    reader.SetFileName('improve.stl')<br>
    reader.Update()<br>
<br>
    # Apply linear extrusion<br>
    extrude = vtk.vtkLinearExtrusionFilter()<br>
    extrude.SetInputConnection(reader.GetOutputPort())<br>
    extrude.SetExtrusionTypeToNormalExtrusion();<br>
    extrude.SetVector(0, 0, -10)<br>
    extrude.CappingOn()<br>
    extrude.Update()<br>
<br>
    # project extruded points onto x-y plane<br>
    z = 1130<br>
    closedSurface = extrude.GetOutput()<br>
    points = closedSurface.GetPoints()<br>
    numPts = closedSurface.GetNumberOfPoints()<br>
    for ptId in range(numPts/2, numPts):<br>
      point = points.GetPoint(ptId)<br>
      points.SetPoint(ptId, point[0], point[1], z)<br>
<br>
    # Create a mapper and actor.<br>
    mapper = vtk.vtkPolyDataMapper()<br>
    mapper.SetInputData(closedSurface)<br>
<br>
    actor = vtk.vtkActor()<br>
    actor.GetProperty().SetColor(colors.GetColor3d("Cornsilk"))<br>
    actor.SetMapper(mapper)<br>
<br>
    # Create a renderer, render window, and interactor<br>
    renderer = vtk.vtkRenderer()<br>
    renderWindow = vtk.vtkRenderWindow()<br>
    renderWindow.SetWindowName("TaperedCylinder")<br>
    renderWindow.AddRenderer(renderer)<br>
    renderWindowInteractor = vtk.vtkRenderWindowInteractor()<br>
    renderWindowInteractor.SetRenderWindow(renderWindow)<br>
<br>
    # Add the actors to the scene<br>
    renderer.AddActor(actor)<br>
    renderer.SetBackground(colors.GetColor3d("DarkGreen"))<br>
<br>
    # Render and interact<br>
    renderWindow.Render()<br>
    renderWindowInteractor.Start()<br>
<br>
<br>
if __name__ == '__main__':<br>
    main()<br>
---<br>
<br>
For your reference.<br>
2018年7月18日(水) 15:44 Jacky Nguyen <<a href="mailto:jackynguyen.km@gmail.com" target="_blank">jackynguyen.km@gmail.com</a>>:<br>
><br>
> Hi Patrick,<br>
><br>
> 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.<br>
> Do you mind taking a look at my code to see what went wrong? I have created a gist here: <a href="https://gist.github.com/ngunhaSO/f3902fd34172a161b678b2a05a5c91fe" rel="noreferrer" target="_blank">https://gist.github.com/ngunhaSO/f3902fd34172a161b678b2a05a5c91fe</a><br>
> I have also attached a stl file that i wanna manipulate and the screenshot of what i achieved here: <a href="https://github.com/ngunhaSO/misc" rel="noreferrer" target="_blank">https://github.com/ngunhaSO/misc</a><br>
><br>
> Thank you!<br>
><br>
> Jacky<br>
><br>
> On Mon, Jul 16, 2018 at 7:48 PM Patrick Bergeron <<a href="mailto:pbergeron@spiria.com" target="_blank">pbergeron@spiria.com</a>> wrote:<br>
>><br>
>> Hi Jacky<br>
>><br>
>><br>
>><br>
>> Let me try to be clearer. Let’s say you have a surface floating in space, which seems to be your case.<br>
>><br>
>><br>
>><br>
>> 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).<br>
>><br>
>><br>
>><br>
>> So set’s say you find a boundary edge with points a and b<br>
>><br>
>><br>
>><br>
>> Add 2 points to your polydata. (xa, ya, 0),  (xb, yb, 0)<br>
>><br>
>><br>
>><br>
>> Then you create a quad that goes like this:<br>
>><br>
>><br>
>><br>
>> (xa,ya,za),<br>
>><br>
>>  (xb,yb,zb)<br>
>><br>
>> (xb,yb,0)<br>
>><br>
>> (xa,ya,0)<br>
>><br>
>><br>
>><br>
>> Or if you prefer you can create 2 triangles:<br>
>><br>
>> (xa,ya,za),<br>
>><br>
>>  (xb,yb,zb)<br>
>><br>
>> (xb,yb,0)<br>
>><br>
>><br>
>><br>
>> (xb,yb,0)<br>
>><br>
>> (xa,ya,0)<br>
>><br>
>> (xa,ya,za),<br>
>><br>
>><br>
>><br>
>><br>
>><br>
>> 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.<br>
>><br>
>><br>
>><br>
>> 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.<br>
>><br>
>><br>
>><br>
>> 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<br>
>><br>
>><br>
>><br>
>> You will end up with a volume with the sides and bottom capped off.<br>
>><br>
>><br>
>><br>
>><br>
>><br>
>> Patrick.<br>
>><br>
>><br>
>><br>
>><br>
>><br>
>><br>
>><br>
>> From: Jacky Nguyen <<a href="mailto:jackynguyen.km@gmail.com" target="_blank">jackynguyen.km@gmail.com</a>><br>
>> Date: Monday, July 16, 2018 at 5:12 AM<br>
>> To: Patrick Bergeron <<a href="mailto:pbergeron@spiria.com" target="_blank">pbergeron@spiria.com</a>><br>
>> Cc: "<a href="mailto:vtkusers@public.kitware.com" target="_blank">vtkusers@public.kitware.com</a>" <<a href="mailto:vtkusers@public.kitware.com" target="_blank">vtkusers@public.kitware.com</a>><br>
>> Subject: Re: [vtkusers] Close the gap between a mesh and a planar<br>
>><br>
>><br>
>><br>
>> Thanks for your input.<br>
>><br>
>> Sorry, I am new to these so I need to take it slowly.<br>
>><br>
>><br>
>><br>
>> Let me clarify a few things:<br>
>><br>
>> 1) by using your approach, i don't need to create the plane on the bottom of the object as a holder?<br>
>><br>
>> 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?<br>
>><br>
>><br>
>><br>
>> 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<br>
>><br>
>><br>
>><br>
>> reader = vtk.vtkSTLReader()<br>
>> reader.SetFileName('path_to_stl')<br>
>> reader.Update()<br>
>><br>
>> triangleFilter = vtk.vtkTriangleFilter()<br>
>> triangleFilter.SetInputConnection(reader.GetOutputPort())<br>
>> triangleFilter.Update()<br>
>><br>
>> # ++++++++++++++++++ extract edges ++++++++++++++++++++++++++++++++++++<br>
>><br>
>> featureEdges = vtk.vtkFeatureEdges()<br>
>> featureEdges.SetInputData(triangleFilter.GetOutput())<br>
>> featureEdges.SetBoundaryEdges(1)<br>
>> featureEdges.SetFeatureEdges(0)<br>
>> featureEdges.SetNonManifoldEdges(0)<br>
>> featureEdges.SetManifoldEdges(0)<br>
>> featureEdges.Update()<br>
>> boundaryMesh = featureEdges.GetOutput()<br>
>> numberOfOpenEdges = featureEdges.GetOutput().GetNumberOfLines()<br>
>> print('number of lines: ', featureEdges.GetOutput().GetNumberOfLines())<br>
>> for i in range(0, boundaryMesh.GetNumberOfLines()):<br>
>>     cell = boundaryMesh.GetCell(i)<br>
>>     cellPoints = cell.GetPoints()<br>
>>     pointIds = cell.GetPointIds()<br>
>>     for j in range(0, pointIds.GetNumberOfIds()):<br>
>>         print('>>> point id: ', pointIds.GetId(j))<br>
>>         print('>>> coordinate: ', boundaryMesh.GetPoint(pointIds.GetId(j)))<br>
>><br>
>><br>
>><br>
>> Thank you,<br>
>><br>
>><br>
>><br>
>><br>
>><br>
>> On Fri, Jul 13, 2018 at 10:10 PM Patrick Bergeron <<a href="mailto:pbergeron@spiria.com" target="_blank">pbergeron@spiria.com</a>> wrote:<br>
>><br>
>> I would take a different approach.<br>
>><br>
>><br>
>><br>
>> I would look at all the edges that have only 1 cell attached, and these are your boundary edges.<br>
>><br>
>><br>
>><br>
>> 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.<br>
>><br>
>><br>
>><br>
>> That approach will create quads all around your geometry connecting to the bottom but will leave the bottom hole open.<br>
>><br>
>><br>
>><br>
>> Next create a cell connecting all your z=0 points together. Make sure they are ordered in sequential order to create your contour loop.<br>
>><br>
>><br>
>><br>
>> Done<br>
>><br>
>><br>
>><br>
>><br>
>><br>
>> Sent from my iPhone<br>
>><br>
>><br>
>> On Jul 13, 2018, at 05:10, Jacky Nguyen <<a href="mailto:jackynguyen.km@gmail.com" target="_blank">jackynguyen.km@gmail.com</a>> wrote:<br>
>><br>
>> 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?<br>
>><br>
>><br>
>><br>
>> The code to create the planar:<br>
>><br>
>><br>
>><br>
>> implicitPolyDataDistance = vtk.vtkImplicitPolyDataDistance()<br>
>><br>
>> implicitPolyDataDistance.SetInput(stl_poly_data)<br>
>><br>
>><br>
>><br>
>> #create a grid<br>
>><br>
>> xCoords = vtk.vtkFloatArray()<br>
>><br>
>> for x, i in enumerate(np.linspace(xmin, xmax,50)):<br>
>><br>
>>     xCoords.InsertNextValue(i)<br>
>><br>
>><br>
>><br>
>> yCoords = vtk.vtkFloatArray()<br>
>><br>
>> for y, i in enumerate(np.linspace(ymin, ymax, 50)):<br>
>><br>
>>     yCoords.InsertNextValue(i)<br>
>><br>
>><br>
>><br>
>> zCoords = vtk.vtkFloatArray()<br>
>><br>
>> for z, i in enumerate(np.linspace(zmin, zmin + 1, 50)):<br>
>><br>
>>     zCoords.InsertNextValue(i)<br>
>><br>
>><br>
>><br>
>> rgrid = vtk.vtkRectilinearGrid()<br>
>><br>
>> rgrid.SetDimensions(x + 1, y + 1 , z + 1)<br>
>><br>
>> rgrid.SetXCoordinates(xCoords)<br>
>><br>
>> rgrid.SetYCoordinates(yCoords)<br>
>><br>
>> rgrid.SetZCoordinates(zCoords)<br>
>><br>
>> signedDistances = vtk.vtkFloatArray()<br>
>><br>
>> signedDistances.SetNumberOfComponents(1)<br>
>><br>
>> signedDistances.SetName("SignedDistances")<br>
>><br>
>><br>
>><br>
>> # Evaluate the signed distance function at all of the grid points<br>
>><br>
>> for pointId in range(rgrid.GetNumberOfPoints()):<br>
>><br>
>>     p = rgrid.GetPoint(pointId)<br>
>><br>
>>     signedDistance = implicitPolyDataDistance.EvaluateFunction(p)<br>
>><br>
>>     signedDistances.InsertNextValue(signedDistance)<br>
>><br>
>><br>
>><br>
>> # add the SignedDistances to the grid<br>
>><br>
>> rgrid.GetPointData().SetScalars(signedDistances)<br>
>><br>
>><br>
>><br>
>> # geometry filter to view the background grid<br>
>><br>
>> geometryFilter = vtk.vtkRectilinearGridGeometryFilter()<br>
>><br>
>> geometryFilter.SetInputData(rgrid)<br>
>><br>
>> geometryFilter.SetExtent(0, x + 1, 0, y + 1, (z + 1) // 2, (z + 1) // 2)<br>
>><br>
>> geometryFilter.Update()<br>
>><br>
>> # ================ END creating a plane =======================<br>
>><br>
>><br>
>><br>
>> The code that merge the stl poly data and the plane:<br>
>><br>
>> meshAppend = vtk.vtkAppendPolyData()<br>
>><br>
>> meshAppend.AddInputData(stl_poly_data)<br>
>><br>
>> meshAppend.AddInputData(geometryFilter.GetOutput())<br>
>><br>
>> meshAppend.Update()<br>
>><br>
>> boundaryClean = vtk.vtkCleanPolyData()<br>
>><br>
>> boundaryClean.SetInputData(meshAppend.GetOutput())<br>
>><br>
>> boundaryClean.Update()<br>
>><br>
>> out = vtk.vtkPolyData()<br>
>><br>
>> out.DeepCopy(boundaryClean.GetOutput())<br>
>><br>
>><br>
>><br>
>> triangleTrans = vtk.vtkTriangleFilter()<br>
>><br>
>> triangleTrans.SetInputData(out)<br>
>><br>
>> triangleTrans.Update()<br>
>><br>
>><br>
>><br>
>> fill = vtk.vtkFillHolesFilter()<br>
>><br>
>> fill.SetInputData(out)<br>
>><br>
>> fill.SetHoleSize(1000000.0)<br>
>><br>
>> fill.Update()<br>
>><br>
>><br>
>><br>
>><br>
>><br>
>> 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: <a href="https://i.stack.imgur.com/F9w3c.png" rel="noreferrer" target="_blank">https://i.stack.imgur.com/F9w3c.png</a><br>
>><br>
>><br>
>><br>
>> Any suggestion to solve this problem?<br>
>><br>
>><br>
>><br>
>> Thank you<br>
>><br>
>><br>
>><br>
>> _______________________________________________<br>
>> Powered by <a href="http://www.kitware.com" rel="noreferrer" target="_blank">www.kitware.com</a><br>
>><br>
>> Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
>><br>
>> Please keep messages on-topic and check the VTK FAQ at: <a href="http://www.vtk.org/Wiki/VTK_FAQ" rel="noreferrer" target="_blank">http://www.vtk.org/Wiki/VTK_FAQ</a><br>
>><br>
>> Search the list archives at: <a href="http://markmail.org/search/?q=vtkusers" rel="noreferrer" target="_blank">http://markmail.org/search/?q=vtkusers</a><br>
>><br>
>> Follow this link to subscribe/unsubscribe:<br>
>> <a href="https://public.kitware.com/mailman/listinfo/vtkusers" rel="noreferrer" target="_blank">https://public.kitware.com/mailman/listinfo/vtkusers</a><br>
><br>
> _______________________________________________<br>
> Powered by <a href="http://www.kitware.com" rel="noreferrer" target="_blank">www.kitware.com</a><br>
><br>
> Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
><br>
> Please keep messages on-topic and check the VTK FAQ at: <a href="http://www.vtk.org/Wiki/VTK_FAQ" rel="noreferrer" target="_blank">http://www.vtk.org/Wiki/VTK_FAQ</a><br>
><br>
> Search the list archives at: <a href="http://markmail.org/search/?q=vtkusers" rel="noreferrer" target="_blank">http://markmail.org/search/?q=vtkusers</a><br>
><br>
> Follow this link to subscribe/unsubscribe:<br>
> <a href="https://public.kitware.com/mailman/listinfo/vtkusers" rel="noreferrer" target="_blank">https://public.kitware.com/mailman/listinfo/vtkusers</a><br>
</blockquote></div>