creating boundary patches in 3D sketch

creating boundary patches in 3D sketch

Anonymous
Not applicable
3,806 Views
35 Replies
Message 1 of 36

creating boundary patches in 3D sketch

Anonymous
Not applicable

Hello everyone,

 

I have a 3D sketch that looks like this:

fwrf.JPG

 

I am trying to create boundary patches to basically patch everything up and turning the sketch into a brep model,  but I am struggling to find out, what path to give to the boundary patch definition object. I tried this:

 

Dim oCircle3d As SketchLine3D
Dim oPath As Path
For Each oCircle3d In oSketch3d.SketchLines3D
 oPath = oDef.Features.CreatePath(oCircle3d)
 Call oBoundaryPatchDef.BoundaryPatchLoops.Add(oPath)
Next

' Create the boundary patch feature based on the definition.
Dim oBoundaryPatch As BoundaryPatchFeature
oBoundaryPatch = oDef.Features _
.BoundaryPatchFeatures.Add(oBoundaryPatchDef)

 

which does not work, with the error message, that oPath is the wrong parameter. I can see why its wrong also, because the feature is looking for one edge loop to create a boundary patch in and I am passing in a lot of edges that create a lot of different edge loops. I also tried creating an edgecollection object, which also did not work, with the exact same error message.

 

Is this solvable?

 

Cheers,

Omar

0 Likes
3,807 Views
35 Replies
Replies (35)
Message 2 of 36

J-Camper
Advisor
Advisor

That looks like a very complex surface you are creating.  You will have to build-in some direction for your API logic, because Inventor on it's own has no idea what your goal is. 

 

Are the lines set up in such a way that you will always have 3 edges to a surface?  It's hard to tell from the picture, but that would help.  It also looks like you have several 3D Sketches, are all the sketchlines in question found in a single sketch?

 

You will need to loop through your collection of lines multiple times to catch all the logic. 

 

Logic 1: limit patches such that each line should be a part of no more than 2 boundary patches. 

Logic 2: each set of lines collected into a patch should be co-planar and create a closed region.

 

I'm sure there are other logic guidelines you will need to implement, but I can't help much without the data set you are using.  If you could post the part in question and manually create the boundary patches you would be expecting, that would be perfect. 

DO NOT POST CONFIDENTIAL DOCUMENTS!!!

0 Likes
Message 3 of 36

Anonymous
Not applicable

Hello JCamper, thanks for your help.

 

I will try to give some background info and provide the part.

 

Basically what I am doing is importing an STL and creating a 3D Sketch based on the STL Points and Edges. So the 3D Sketch looks exactly like the Mesh. Then I would manually click every three edges that create one mesh surface (since its triangulated) to create a surface that can then be thickened up. I hope these screenshots make it more clear. These screenshots create the boundary patches directly from the mesh edges, but I think the approach should be the same for 3D sketches and a mesh or?

 

Bild5.png

 

Bild1.png

 

Bild2.jpg

 

Bild3.png

Bild4.jpg

 

 

Will also post the part later!

0 Likes
Message 4 of 36

J-Camper
Advisor
Advisor

The triangulated restriction on the mesh lines will make this much easier since we have a fixed number of lines to create a valid path.  I will keep my eye out for the part whenever you post it.

0 Likes
Message 5 of 36

Anonymous
Not applicable

Here is the partfile (sorry could not make it yesterday).

 

You will see the converted mesh and a 3D sketch that is created via VBA Code. Now if I use the 3D sketch or the mesh directly does not play a huge role to me, so if it is possible to do it with the triangulated restriction it would get me a huge step forward. 

 

What exactly I was trying to do can be understood through the earlier posted screenshots I think?

 

Thanks in advance

0 Likes
Message 6 of 36

J-Camper
Advisor
Advisor

Hello @Anonymous ,

 

After looking at your part and I believe I understand your end goal, but I think a different workflow is all you need. 

 

Process Screen Shot:

temp_pic.jpg

 

Process Explanation:

1) Make a plane offset from the XY Plane to determine a cutoff point. [Could be included as a Template file to save a step]

2) Sculpt the Converted Mesh you supplied in the part file. [As long as all your meshs come in watertight, like this one, this feature will work]

3) Split, Trim using CutPlane from (1)

4) Shell, Outside, @ 5mm, 1 face removed is the face created by (3)

4) Shell Options reference4) Shell Options reference

 

Unless you have a lot of parts to process this way, I don't think you need to do it through API.  Let me know if this workflow is unacceptable or if you need to process a lot of parts this way and we can start to automate the process.

 

I attached the part with this workflow.

Message 7 of 36

Anonymous
Not applicable

Hello @J-Camper ,

 

thanks for your help. This workflow really is much better. I think if it would come down to modeling only this kind of STL files i would use it. This project though focuses on the automatic modeling of lots of different shapes, which I think makes it necessary so create faces on each triangulated surface and then working with the created shells from there on.

 

Yesterday I tried the following:

 

' Set a reference to the component definition.
Dim oCompDef As PartComponentDefinition
oCompDef = oPartDoc.ComponentDefinition

Dim oEdgeColl As EdgeCollection
oEdgeColl = invApp.TransientObjects.CreateEdgeCollection
Dim oEdge As EdgeLoop
Dim oFace As Face
Dim oBoundaryPatch As BoundaryPatchFeature
Dim oBoundaryPatchDef As BoundaryPatchDefinition
' Collect up the edges to create boundary patch.

For Each oFace In oSurfaceBody.Faces
For Each oEdge In oSurfaceBody.Faces.Edgeloops
oEdgeColl.Add(oEdge)
Next
oBoundaryPatchDef = oCompDef.Features.BoundaryPatchFeatures.CreateBoundaryPatchDefinition
Call oBoundaryPatchDef.BoundaryPatchLoops.Add(oEdgeColl)
oBoundaryPatch = oCompDef.Features.BoundaryPatchFeatures.Add(oBoundaryPatchDef)
Next

 

Basically I was trying to loop trough the faces of the surfacebody (mesh) and in each iteration take the edgeloop of the face and store it in the edge collection, then create the face while still being in the for-loop, so it can create the next face in the next iteration with the next edgeloop. This again did not work, but I feel like this time it is more an understanding the Inventor API issue and my terrible coding skills. Do you think this would work?

 

Thanks

 

 

0 Likes
Message 8 of 36

JhoelForshav
Mentor
Mentor

Hi @omar.abumarkhieh 

Are you looking for something like this maybe? 🙂

Dim oPartDoc As PartDocument = ThisDoc.Document
Dim oCompDef As PartComponentDefinition = oPartDoc.ComponentDefinition
Dim oFeatures As PartFeatures = oCompDef.Features
Dim oFaces As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
For Each oSurf As WorkSurface In oCompDef.WorkSurfaces
 For Each oSurfBod As SurfaceBody In oSurf.SurfaceBodies
  For Each oFace As Face In oSurfBod.Faces
   Dim oBPdef As BoundaryPatchDefinition = oFeatures.BoundaryPatchFeatures.CreateBoundaryPatchDefinition
   oBPdef.BoundaryPatchLoops.Add(oFace.EdgeLoops(1))
   oFaces.Add(oFeatures.BoundaryPatchFeatures.Add(oBPdef).SurfaceBodies(1))
   ThisApplication.UserInterfaceManager.DoEvents()
  Next
 Next
Next
Dim oKnit As KnitFeature = oFeatures.KnitFeatures.Add(oFaces, , True)

 

0 Likes
Message 9 of 36

JhoelForshav
Mentor
Mentor

I tried to include a screencast in the post but that didn't seem to work...

So here's the link to the screencast:

https://knowledge.autodesk.com/community/screencast/9b158824-a9fa-4f9d-8c87-ab130feb4f61

 

EDIT: and just as I posted this the screencast appeared in my previous post 😄

0 Likes
Message 10 of 36

J-Camper
Advisor
Advisor

The reason I initially switched workflows is the trouble I was having with the thicken command.  All the faces on the Converted mesh are thickenable, and in isolated sections they work, but there are some internal faces you want to avoid which is easy enough and then there are also some troublesome faces on the tip of the finger.  I got around this by filtering out faces from the Converted Mesh surface you included in your part by verifying that each edge on a face was only connected to 2 faces before I added it to the collection.  The 3 Interior faces have edges touching only 1 face [itself], and then another 3 or 4, I can't remember, had edges touching 9+/- Faces.  When I excluded those surfaces I could thicken 2 mm but not 5 mm, and there was a hole at the finger tip where those 3-4 faces were not selected.

 

Because I could not get a thicken to work with all the desired faces, I decided to try a different route.  The workflow I show can be automated as long as you always start with a water tight mesh, and even without a water tight mesh you could probably implement a patching subroutine to only add patches at holes and then includes the patches with the Converted Mesh in the sculpt command.

 

If you want help trying to automate the workflow I presented in my earlier blog post, I'll help with that, but I don't think working around a Thicken workflow will give the desired output.

0 Likes
Message 11 of 36

Anonymous
Not applicable

Hello @JhoelForshav  

 

yes this was it exactly! Thank you!

0 Likes
Message 12 of 36

Anonymous
Not applicable

Yeah i see your point. How would you start automating the process? Do you think it could be segmented, so I could potentially combine functionalities from this workflow with my workflow to create a collection of routines that all together make it possible to import STL files and depending on what needs to be done create geometry around it or cut it at a specific area or create boundary patches for a specific area of the mesh etc.?

 

Im thinking about something like a VBA Userform that includes Buttons, kind of like

 

#1 Button - Import

#2 Button - Sculpt mesh

#3 Button - Cut with offset planes from all three working planes

#4 Button - Create Draft or Shell of customized mesh

#5 Button - Create Boundary Patches depending on the surface of customized mesh

 

What do you think?

 

0 Likes
Message 13 of 36

J-Camper
Advisor
Advisor

I don't think you need user interaction for each step. 

 

-I would take your converted mesh and attempt to sculpt. [at the end of your import script or as a separate rule entirely]

 

-If the sculpt fails I would run through a process of looking for openings in the mesh [not exactly sure how that looks off the top of my head]

          -Try sculpt again with converted mesh and patch surfaces as input

          -If it doesn't work at this point, hard to tell what to do without a little trial and error to get the boundary patch creation portion working properly

 

-If the scupt doesn't fail try move straight into the split.

 

-After split the last index in the faces enumerator on our sculpted solid should the the face resulting from the cut [you could build in a check for createdby feature if needed].  This is also the face we want to mark as removing during the shell feature

 

-I didn't have any failures on the shell feature, but we might want to test several different meshs to be sure it is consistent.

 

If you want to break the process up more you could and then have a button to perform each step, it's just not the way I would approach automating this process

0 Likes
Message 14 of 36

Anonymous
Not applicable

Im still struggling with the Inventor API I think. I am trying to figure out how to sculpt the mesh via the API. I tried to create the Sculptfeature and give it an Object, which here is the surface body, but its not working. 

 

Dim osurface As WorkSurface
osurface = oSurfaceBody

For Each osurface In oDef.WorkSurfaces

oSurfaces.Add(oFeas.SculptFeatures.CreateSculptSurface(osurface, PartFeatureExtentDirectionEnum.kNegativeExtentDirection))

Next

 

Dim oSculpt As SculptFeature

oSculpt = oFeas.SculptFeatures.Add(oSurfaces, PartFeatureOperationEnum.kNewBodyOperation)

 

It looks like this. Can you point me in the right direction? @J-Camper 

0 Likes
Message 15 of 36

J-Camper
Advisor
Advisor

@Anonymous,

You have to convert the WorkSurface into a SculptSurface before using it:

'Our part componentDefinition
Dim pDef As PartComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition
'Our Surface Colection
Dim SurfCol As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
'Creating a SculptSurface Object from our original WorkSurface
Dim NewSculptSurf As SculptSurface = pDef.Features.SculptFeatures.CreateSculptSurface(pDef.WorkSurfaces.Item(1), PartFeatureExtentDirectionEnum.kSymmetricExtentDirection)
'Selecting initial surface:
SurfCol.Add(NewSculptSurf)
'Setup new ScupltFeature
Sculpting :
Dim newSculpt As SculptFeature = pDef.Features.SculptFeatures.Add(SurfCol, PartFeatureOperationEnum.kNewBodyOperation)
If newSculpt.SurfaceBodies.Item(1).Volume(0.0001) > 0
	MessageBox.Show("Scuplt Did create a solid body.", "New Body! :)")
Else
	MessageBox.Show("Scuplt Did not create a solid body. Sculpt feature will be removed.", "No New Body :(")
	newSculpt.Delete(True, True, True)
	'I think we could just add surfaces to the collection affter sculpt is deleted
	'Probably setup a custom function as ObjectCollection to gather newly created patches
	'The function would have subroutines to find un un-closed areas of mesh and create surface
	'Then loop through that surface and add to sculpt collection
	'For Each Item In MyCustomFunction()
		'SurfCol.Add(pDef.Features.SculptFeatures.CreateSculptSurface(Item, PartFeatureExtentDirectionEnum.kSymmetricExtentDirection))
	'Next
	'GoTo Sculpting
End If

I did minor testing and the scuplt feature does not fail even if the selected surface is not watertight, so I added a check for the newly created SurfaceBody to make sure it has a valid Volume. 

 

Let me know if you have any questions or if the code is producing errors.

 

0 Likes
Message 16 of 36

Anonymous
Not applicable

This works perfectly. Thanks a lot!

 

I moved on to create the offset plane and then the split feature. This is where im struggling again. 

 

        Dim oExtrudeSurface As ExtrudeFeature
        Dim oWorksurface As WorkSurface

        For Each oExtrudeSurface In oDef.Features.ExtrudeFeatures
            If oExtrudeSurface.Definition.Operation = PartFeatureOperationEnum.kSurfaceOperation Then
                oWorksurface = oExtrudeSurface.SurfaceBody.Parent
                Debug.Print(oExtrudeSurface.Name)

                oDef.Features.SplitFeatures.SplitFaces(oWorksurface, True)
            End If
        Next


 

This is what I found, but Im guessing I should not look for extrude features to split? Am kind of lost here because I dont really understand how the api works and what is needed to create specific features. Creating the plane was fairly simple though.

 

I hope you dont mind me continuously asking @J-Camper  

 

0 Likes
Message 17 of 36

J-Camper
Advisor
Advisor

So you have your sculpt feature and need to do the body cut next.  Are you going to create a cut plane from scratch or set up a template file to load your mesh into?

 

I actually spent a little time the other night trying to get a mesh patching Function to work, because I have never done it before and was curious.  I can find the a hole and patch it but get an error trying to redo the sculpt with 2 SculptSurfaces In the SurfCol Object Collection.  The code below is what I was working on along with a Sub Routine to Split the sculpted body:

Sub Main
	If ThisApplication.ActiveDocumentType <> kPartDocumentObject Then MessageBox.Show("This rule is designed to only work in part documents.", "Wrong Document Type") : Exit Sub
	'I'm separating the code so it is easy to add to other code
	Call MeshProcessing(ThisApplication.ActiveDocument)
	
End Sub

Sub MeshProcessing(pDoc As PartDocument)
	Dim pDef As PartComponentDefinition = pDoc.ComponentDefinition
	Dim SurfCol As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	Dim NewSculptSurf As SculptSurface = pDef.Features.SculptFeatures.CreateSculptSurface(pDef.WorkSurfaces.Item(1), PartFeatureExtentDirectionEnum.kSymmetricExtentDirection)
	SurfCol.Add(NewSculptSurf)
	'Setup new ScupltFeature
	Dim FirstPass As Boolean = True
	Dim newSculpt As SculptFeature
	Sculpting :
	newSculpt = pDef.Features.SculptFeatures.Add(SurfCol, PartFeatureOperationEnum.kNewBodyOperation)
	'Verify Scuplt has volume
	If newSculpt.SurfaceBodies.Item(1).Volume(0.0001) > 0
		MessageBox.Show("Scuplt did create a solid body.", "New Body! :)")
		'Now we can split the body
		Dim OurNewBody As SurfaceBody = newSculpt.SurfaceBodies.Item(1)
		Call SplitThis(OurNewBody, pDef)
	Else If FirstPass = True
		FirstPass = False
		MessageBox.Show("Scuplt Did not create a solid body. Sculpt feature will be removed.", "No New Body :(")
		
		MessageBox.Show("I found  " & MyCustomFunction(SurfCol.Item(1).Surface, pDef).Count & " to fill holes in mesh, but currently failing to implement.", "Unfinished Processing")
		'I can find and make a Patch but Struggling with encorperating it with failed surface
		'So I'm skipping the next section
		GoTo SkipForNow
		
		'newSculpt.Delete() 'Currently unsure if it is better to add surfaces to an existing scuplt or figure out what the new scuplt is failing with 2 SculptSurfaces
		
		For Each Item In MyCustomFunction(SurfCol.Item(1).Surface, pDef)
			SurfCol.Add(pDef.Features.SculptFeatures.CreateSculptSurface(Item, PartFeatureExtentDirectionEnum.kSymmetricExtentDirection))	
			'newSculpt.Surfaces.Add(pDef.Features.SculptFeatures.CreateSculptSurface(Item, PartFeatureExtentDirectionEnum.kSymmetricExtentDirection))
		Next
		
		GoTo Sculpting
SkipForNow:
	Else
		MessageBox.Show("I tried once to close the mesh but it didn't work.", "I Failed :(")
		Exit Sub
	End If
End Sub

Sub SplitThis(Body As SurfaceBody, Def As PartComponentDefinition)
	'Dim TempDef As PartComponentDefinition
	'TempDef.Features.SplitFeatures.TrimSolid(CutPlane, Body, True)
	Dim CutPlane As WorkPlane
	'Find existing:
	For Each wkPlane As WorkPlane In Def.WorkPlanes
		If wkPlane.Name = "CutPlane" 'Or what ever name you want to use for the work plane
			CutPlane = wkPlane
		End If
	Next
	'Check if we have a Plane
	If IsNothing(CutPlane)
		CutPlane = Def.WorkPlanes.AddByPlaneAndOffset(Def.WorkPlanes.Item(3), "50 mm", False) 'Plane 3 is XY Plane
		CutPlane.Name = "CutPlane"
	End If
	'Now we have our Plane and body
	Dim NewSplitFeat As SplitFeature = Def.Features.SplitFeatures.TrimSolid(CutPlane, Body, True)
End Sub

Function MyCustomFunction(wrkSurf As WorkSurface, Def As PartComponentDefinition) As ObjectCollection
	'Setup
	Dim Result As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	Dim oneFaceEdges As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	Dim BoundaryPatchDef As BoundaryPatchDefinition = Def.Features.BoundaryPatchFeatures.CreateBoundaryPatchDefinition()
	Dim BoundaryPatchFeat As BoundaryPatchFeature
CheckEdgeLoops :
	For Each ed As Edge In wrkSurf.SurfaceBodies.Item(1).Edges
		If ed.Faces.Count = 1 Then oneFaceEdges.Add(ed)
	Next
	'MessageBox.Show(oneFaceEdges.Count, "Edges on 1 Face")
	'Sketch for boundaries
	Dim sk As Sketch3D = Def.Sketches3D.Add()
	sk.Edit
	For Each Item In oneFaceEdges
		sk.Include(Item).Construction = False
	Next
	sk.Profiles3D.AddClosed
	'MessageBox.Show(sk.Profiles3D.Count, "Title")
	sk.ExitEdit
	'Patch from sketch
	For Each Prof As Profile3D In sk.Profiles3D
		BoundaryPatchDef.BoundaryPatchLoops.Add(Prof)
		BoundaryPatchFeat = Def.Features.BoundaryPatchFeatures.Add(BoundaryPatchDef)
		For Each newSurf As WorkSurface In Def.WorkSurfaces
			If newSurf.SurfaceBodies.Item(1).CreatedByFeature.ExtendedName = BoundaryPatchFeat.ExtendedName Then Result.Add(newSurf) : Exit For
		Next
	Next
	'MessageBox.Show(Result.Count, "Title")
	Return Result
End Function

 

I put the whole mesh Processing bit of code, which I posted earlier, into a sub routine so it is easy to incorporate with what ever rule you want.

 

I tested the Split and it is working, but let me know if you have any questions or need help with anything else along the road.

0 Likes
Message 18 of 36

Anonymous
Not applicable

Hello @J-Camper , your code worked perfectly fine! Thank you so much for your help so far.

0 Likes
Message 19 of 36

Anonymous
Not applicable
0 Likes
Message 20 of 36

J-Camper
Advisor
Advisor

@Anonymous,

 

I will post in both blog posts, but I added a subroutine for the shell procedure to the rule I posted last time.  I will also attach the file i was using to play with the non-watertight scenario.  I'm still having issues with using the patches I can make, so some more work needs to be done there, but the process for a watertight mesh import works as desired. 

 

I am attaching the rule as a .txt file so you don't have to read through an entire blog post.  Let me know if you need anymore help

0 Likes