creating boundary patches in 3D sketch

creating boundary patches in 3D sketch

Anonymous
Not applicable
3,812 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,813 Views
35 Replies
Replies (35)
Message 21 of 36

J-Camper
Advisor
Advisor

@Anonymous,

 

I don't know if you've moved on from this already, but I was driven to develop a mesh patching script in the case the import ever failed to create a watertight mesh properly.  I attached my test file.  The file was last saved in testing mode, where I run SurfaceBodies.Item(2) which has faces deleted from it.  You can edit the Delete Face Feature to change/add holes to patch. 

 

Test mode can be disabled by changing the main sub by changing True To False inside the Sub Call to make it use SurfaceBodies.Item(1) [presumably the converted mesh]:

 

Sub Main
	If ThisApplication.ActiveDocumentType <> kPartDocumentObject Then MessageBox.Show("This rule is designed to only work in part documents.", "Wrong Document Type") : Exit Sub
	'Doesn't need to be separate, but this makes it easier to integrate
	Call MeshProcessing(ThisApplication.ActiveDocument, True)'True to enter testing mode in sample non-water tight part	
End Sub

 

 

Let me know if you have any questions.

 

0 Likes
Message 22 of 36

Anonymous
Not applicable

Hey, @J-Camper  sorry for the late reply. I tried deleting faces and running the script without entering "testmode" and it worked fine. Should it behave like that? I would be interested to include a similiar functionality in case the model isnt watertight (which it usually will be, but just in case). I will try again according to your instructions and will get back to you.

 

I am also trying to include a "configurator"-type function with the script, meaning after the script is finished there will be a button which calls a new userform, where all parameters are listed with textboxes to type in desired values and an update button. I have managed to access the parameters but am struggling with two things. One is how to get to the parameter method that gets me the property of a parameter where the feature that created the parameter is stored (so the user knows what this value will be effected by). The other one is how to make a list of all available parameters. I know it will be next to impossible to get it in a userform but maybe you have an idea that could help me displaying the parameters in a way that makes it usable as a configurator, meaning without iterating trough all parameters and displaying them one by one.

 

Configurator_1.JPG

 

I know so far it is only the shell feature and the offset-plane that could be configured which is already enough. 

 

Cheers Omar

0 Likes
Message 23 of 36

J-Camper
Advisor
Advisor

Using only the test file I previously attached, If you Call the sub routine like this:

 

Call MeshProcessing(ThisApplication.ActiveDocument, True)'True to enter 

 

It will run with the 2nd Surface body, which is affected by the Delete Face Command

 

If you call it like this:

 

Call MeshProcessing(ThisApplication.ActiveDocument, False)'True to enter 

 

It will run with the 1st SurfaceBody, which is what you supplied.

 

As Far As Collecting The driving parameters, you could collect from the Features themselves [Most features with dimensions have a "Parameters" Property], Name them on feature creation to collect afterwards [Error handling may be required if Parameter names are already used], or create your user parameters at the beginning and use those parameter names to execute the feature creations.

 

I would go with the Parameter set up before, because you can verify the parameters exist/make them at the beginning and then just reference the Parameter name everywhere it is needed. 

 

Let me know if you have any further questions.

 

 

0 Likes
Message 24 of 36

Anonymous
Not applicable

I managed to create the userparameters. How would i go by connecting them to the feature creation? Could I just reference the userparameter name as one of the creation parameters or maybe through feature.parameters method?

 

Also fur the cutting plane no parameters property exists. How could I handle this?

 

Thanks  

0 Likes
Message 25 of 36

J-Camper
Advisor
Advisor

I'm not sure how you created the User parameters, but this is how I was thinking: [Only posting new first part of the "MeshProcessing" Subroutine]:

 

Sub MeshProcessing(pDoc As PartDocument, Testing As Boolean)
	Dim pDef As PartComponentDefinition = pDoc.ComponentDefinition
	
	Dim ParamList As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
	ParamList.Add("CutPlaneOffset", "50 mm")
	ParamList.Add("ShellThickness", "5 mm")
	
	For i = 1 To ParamList.Count
		Try
			Param = pDef.Parameters.Item(ParamList.Name(i))
			Param.Expression = ParamList.Value(ParamList.Name(i)).ToString
		Catch
			'Below would add as user parameter
			pDef.Parameters.UserParameters.AddByExpression(ParamList.Name(i), ParamList.Value(ParamList.Name(i)).ToString, UnitsTypeEnum.kMillimeterLengthUnits)
		End Try
	Next

 

Then when you call the other subroutines later in "MeshProcessing", I would just add a variable to each subroutine for the Parameter name: [Only posting modified last part of the "MeshProcessing" Subroutine]:

 

'Now we can split and shell the new body
	Dim OurNewBody As SurfaceBody = newSculpt.SurfaceBodies.Item(1)
	Call SplitThis(OurNewBody, pDoc, ParamList.Name(1))
	Call ShellThis(OurNewBody, pDoc, ParamList.Name(2))
	
	'End of current Process
	InventorVb.DocumentUpdate()
	
End Sub

 

With the User parameter already created, you can just feed the Paramter name for the Feature Parameters.  Edited Subroutines:

 

Sub SplitThis(Body As SurfaceBody, oDoc As PartDocument, PlaneOffest As String)
	
	Dim Def As PartComponentDefinition = oDoc.ComponentDefinition
	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), PlaneOffest, False) 'Plane 3 is XY Plane
		CutPlane.Name = "CutPlane" 'Or what ever name you want to use for the work plane
		
	End If
	'Now we have our Plane and body
	Dim NewSplitFeat As SplitFeature = Def.Features.SplitFeatures.TrimSolid(CutPlane, Body, True)
	
End Sub
Sub ShellThis(Body As SurfaceBody, oDoc As PartDocument, shThickness As String)
	
	Dim Def As PartComponentDefinition = oDoc.ComponentDefinition
	
	Dim existingBody As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	existingBody.Add(Body)
	Dim OurNewFace As FaceCollection = ThisApplication.TransientObjects.CreateFaceCollection
	'Select the face we created with our split feature
	For Each f As Face In Body.Faces
		If f.CreatedByFeature.Type = ObjectTypeEnum.kSplitFeatureObject
			OurNewFace.Add(f)
		End If
	Next
	'Define Shell and create Shell Feature
	Dim ShellFeatDef As ShellDefinition = Def.Features.ShellFeatures.CreateShellDefinition(OurNewFace,"0.0001", ShellDirectionEnum.kOutsideShellDirection)
	Dim ShellFeat As ShellFeature = Def.Features.ShellFeatures.Add(ShellFeatDef)
	ShellFeat.SetAffectedBodies(existingBody)
	ShellFeat.Parameters.Item(1).Expression = shThickness
	
End Sub

 

 

I also attached a text file with full updated rule.

 

Let me know if you have any questions

0 Likes
Message 26 of 36

Anonymous
Not applicable

Hello @J-Camper 

 

I have an issue with the try and catch statements. I get an error when starting the script telling me that "param" has not been declared. Do I have to add a "Dim param as ..." somewhere or should it work like this without declaring it?

 

Thanks you have been a great help to me

0 Likes
Message 27 of 36

Anonymous
Not applicable

hello again @J-Camper 

 

i managed to get it to work. I had to create a Form1.param field. I don't know exactly what that means but it is working according to plan now! 

0 Likes
Message 28 of 36

J-Camper
Advisor
Advisor

Glad you've got it working. 

 

I typically don't have an issue with using "Param", without declaring it.  The way I'm using it, "Param" does not get referenced/used in anyway after the Try so, if you are using/referencing it after the Try, that might be a reason why.  I also don't do a lot with iLogic created/launched forms, so that might be another reason why. 

 

 

0 Likes
Message 29 of 36

Anonymous
Not applicable

Hello @J-Camper  just a quick question

 

The try and catch statements.. how does it work exactly? I do not understand why we are assigning Name and Value of "ParamList" to the "Param" variable, but not using it in the Catch statement. Asking just out of curiosity. Is its function more of a check?

 

Cheers

0 Likes
Message 30 of 36

J-Camper
Advisor
Advisor

Let me break down that part of the rule a bit more.

 

First I used a NameValueMap so I could have the parameter name and its initial value in a single object that can be easily added to without changing the code.  It could be accomplished with 2 separate lists, 4 individual strings or even "hard-coded". [Note: Names must be unique but Values can be repeated when setting up a NameValueMap]

	Dim ParamList As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
	ParamList.Add("CutPlaneOffset", "50 mm")
	ParamList.Add("ShellThickness", "5 mm")

 

Then the first part of the try is there to cover the event that these parameter names are already in use.   If the parameter already exists, the the "Try" is successful and the "Catch" is skipped.  The "Try" selects the parameter by name and then the next line sets the parameter expression with the Value from our NameValueMap.  The Name is reference by Item Index (i) and the Value is referenced by the Name.

For i = 1 To ParamList.Count
		Try
			Param = pDef.Parameters.Item(ParamList.Name(i))
			Param.Expression = ParamList.Value(ParamList.Name(i)).ToString
		

 

If the Parameter name is not in use then we fail to set "Param" in the first line of the "Try" and that triggers the "Catch", without finishing the "Try" statement.  Inside the "Catch" we are creating a new User Parameter by use of the "AddByExpression" Method  where we set the (Name, Expression, Unit Type) for our new parameter.  We are using the .Name Property and the .Value Property of the NameValueMap "ParamList" to set these values, and then I set the unit type to mm with the UnitsTypeEnum as a generic setting for this part.  The Name is reference by Item Index (i) and the Value is referenced by the Name.

Catch
			'Below would add as user parameter
		pDef.Parameters.UserParameters.AddByExpression(ParamList.Name(i), ParamList.Value(ParamList.Name(i)).ToString, UnitsTypeEnum.kMillimeterLengthUnits)
		End Try
	Next

 

In short the Try/Catch is a form of Error Handling.  You put something into the Try portion that has the possibility of failing, then the Catch is there to handle that error if it occurs. 

 

Let me know if you have any other questions.

0 Likes
Message 31 of 36

Anonymous
Not applicable

Thanks so much!

 

I have now moved on with the script, meaning Im trying to expand its functionality to other 3D Scans/STL Files. Mostly Scans of body parts. The goal is to create highly customized geometry depending on whatever scan is being used. The next model Im using is a scan of a foot, with the goal to create customized foot insoles. The steps I believe would not change. The part needs to be sculpted, trimmed and the shellfeature will create the actual geometry that will be the insole. 

I have already encountered an issue. The sculpting is not working and i cant figure out what the issue is. Maybe you can take a look?

 

Also: Do you think it would be possible to create the feature depending on user data that is being asked for after starting the script? For example the cutting plane needs to be created in XY, XZ or YZ and depending on what the user want he can enter or choose the axis. 

 

Same goes for the shell feature, where it could be possible that no face should be deleted while creating and then other times it needs to be deleted.

 

What do you think?

0 Likes
Message 32 of 36

Anonymous
Not applicable

Sorry forgot to add the file

0 Likes
Message 33 of 36

Anonymous
Not applicable

I also tried to use  the custom function to patch the stl file and get the sculpt to work. At first i recieved an error when checking for the volume of the sculpt, so it never reached the function. Then I enveloped everything in a try and catch statement and am receiving this error now:

 

Unbeneannt.JPG

0 Likes
Message 34 of 36

hfcandrew
Advisor
Advisor

I made custom foot insole and AFOs for a living, about 4000 pairs a year. If you are using scans of a foot and .stl file, Meshmixer is the way simpler and faster and more accurate way to go.

 

Watch:

https://drive.google.com/file/d/1PCgWTQDufiNSGUoZf5hY8sBXKpSr9Otk/view?usp=sharing

 

I use the same kids of process to do many different types of orthtics/insoles. And I automate the process with a custom program I made based on the mmAPI.

0 Likes
Message 35 of 36

Anonymous
Not applicable

Hi @hfcandrew  thanks for your input.

 

I realize that Meshmixer or any other sculpting program is way more efficient for this kind of tasks. Im using inventor now simply because I already invested a lot of time in the development and want to see how far i can push it. Its just a small project for my university studies, so no real commercial use.

 

Cheers, 

Omar

 

0 Likes
Message 36 of 36

J-Camper
Advisor
Advisor

@Anonymous,

 

This surface is a lot more complex than the previous sample.  It has a lot of odd, overlaping faces on the leg portion, and fails to create a valid solid when including faces kind of mid-ankle up [53mm above XY Plane is last valid point for this sample].  I had to use a different workflow to get a valid solid:

 

Project cut plane

Extrude(New Solid) bounding box

Sculpt(Cut) the new solid and surface so that intersection is left

 

If this is meant to focus on the sole of the foot, then this approach might be fine.  I think the tunnel-like surface collection, at the meeting of the big toe and first toe, is causing failures with the Shell Feature on the new solid.  I have not tried to automate this process yet it can definitely be done up to this point, but I'm not sure how you wanted to use the foot model.  I have attached a part with the new manual workflow.

0 Likes