This is part 4 of 7 in this blog series, where I explain the Product Modeler in the 3DEXPERIENCE (3DX), which is probably the most convoluted subject!
For reference, here are all of the blogs in this series, Transitioning Macros from CATIA V5 to the 3DEXPERIENCE:
Part 1: Framework
Part 2: Creating, Opening, and Saving Files
Part 3: Services
Part 4: Product Modeler
Part 5: Part Modeling and Drafting
Part 6: Selections
Part 7: Deployment
---------------------------------------------------------
Product Modeler Article
There is an article explaining the 3DX Product Modeler which I do recommend you read as it's quite good, gradually introducing the concepts onto which the Product Modeler relies, using the example of the skateboard assembly. To access the article, open the 3DX Automation documentation and go to Common Services > PLM Modelers > Product > Product Modeler Overview, as shown in Figure 1.
In this post, I’ll try to present a condensed version of the article, as well as the comparison of V5 and 3DX product modelers.
Figure 1
Instance/Reference Model
One of the key requirements for a good product modeler is avoiding data duplication. Both V5 and 3DX address this requirement through the Instance/Reference model.
Consider a car wheel assembly. It consists of, among others, the tire, the wheel rim, and five lug nuts. Now, each of the five lug nuts is the same geometrical shape, same part – and it’s called “Reference”. And the five occurrences of the lug nut within the wheel assembly are called “Instances” of that “Reference” part. Of course, each Instance has its own position within the Product, so the position of the part resides in the Instance.
As a result, the car wheel product model does not need to load five lug nut shapes. The product model only consists of Instances, with each Instance being essentially a link to its Reference part (plus the position of the part within the product). That’s why, if you have noticed, CATProduct files are usually much smaller than CATPart files. This way, the duplication of data is avoided, so when a Product is opened, the system only loads one Reference model for each lug nut.
If you look at the V5 Product object diagram, each Product in the Products collection is an Instance.
Figure 2
And, being an Instance, each Product object has a property ReferenceProduct, which is the link to its Reference.
There’s one more thing here, which is Representations. The folks at Dassault thought – what if a part might have different shapes and forms, depending on its intended use? Such as – a simplified representation? Or a finite element model? So they implemented this functionality through Representations, i.e., a Reference may have several different shapes and forms – the Representations.
In V5, this is done through several methods owned by the Product object, shown in Figure 3.
Figure 3
In 3DX, the Instance/Reference model is quite similar, but there are some differences too.
First, 3DX splits the Representation object onto a Representation Reference and a Shape. Why? The Product Modeler article says this is because logically the Shape belongs to the Part Modeler domain, while Representation belongs to the Product Modeler. From the scripting point of view, however, the objects are hardly distinct. The Representation Reference aggregates the Shape, therefore deleting one deletes the other too.
Figure 4
Occurrence Model
Second, 3DX makes a distinction between the “persistent” product model, as it is stored in the DB, and the “session” model, as opened in your 3DX session.
The Instance/Reference model is the persistent one, which represents how the model is stored in the DB. However, the product is displayed differently in the 3DX window.
If we take the example of the car wheel assembly, the Instance/Reference model has only one lug nut shape in the product structure. However, when we open the assembly in session, we see five lug nuts instead of one. So, what you see in the 3DX session is built on the Occurrence model, which is created from the Instance/Reference model.
The Occurrence model is not persistent, i.e., it’s not saved in the DB. It is re-built whenever a Product is loaded into session. Both models reside in the session memory and can be accessed programmatically.
What difference does it make? Not too much, but it does. Specifically, when you search through your Product, you’re searching through what you see on the screen, which is the Occurrence model, not the Instance/Reference model. But more on that later.
Product Object Diagram
The 3DX Product object diagram is shown in Figure 5.
VPMInstance, VPMReference, VPMRepInstance, and VPMRepReference objects are related to the Instance/Reference model.
VPMOccurrence objects are related to the Occurrence model. Note that the VPMOccurrence objects hold pointers to their VPMInstance counterparts. Therefore, from the programmer’s standpoint, once the Product is opened in session, VPMOccurrence and VPMInstance objects are essentially the same thing.
Figure 5
Navigating Instance/Reference Model
The flow diagram is presented in Figure 6. Similarly to V5, you need to use a recursive procedure to visit all components in a Product.
You start with obtaining the VPMRootOccurrence object, which is the Product’s root. From there, you obtain it’s VPMReference, and then start iterating over the VPMInstances collection. For each VPMInstance in the collection, you obtain its VPMReference and loop through its own VPMInstances. And so on, digging deeper and deeper into the product structure.
Figure 6
The sample code is shown below.
01: Sub CATMain()
' Product Root Occurrence
02: Dim oEditor As Editor
03: Set oEditor = CATIA.ActiveEditor
04: Dim oPLMProductService As PLMProductService
05: Set oPLMProductService = oEditor.GetService("PLMProductService")
06: Dim oRootOcc As VPMRootOccurrence
07: Set oRootOcc = oPLMProductService.RootOccurrence
' Product Root Reference
08: Dim oVPMRef As VPMReference
09: Set oVPMRef = oRootOcc.ReferenceRootOccurrenceOf()
' Go into the Root Product, calling the recursive procedure
10: NavigateReferenceStructure oVPMRef
11: End Sub
12: Sub NavigateReferenceStructure(oVPMRefIn As VPMReference)
' Loop through the collection of child-instances
13: Dim i As Integer
14: For i = 1 To oVPMRefIn.Instances.Count
' get the i-th Instance
15: Dim oVPMInst As VPMInstance
16: Set oVPMInst = oVPMRefIn.Instances.Item(i)
' get its VPMReference
17: Dim oVPMRef As VPMReference
18: Set oVPMRef = oVPMInst.ReferenceInstanceOf()
'... put your code here to work with the instance and/or reference
' Recursively, go into the i-th Instance to get to its children
19: NavigateReferenceStructure oVPMRef
20: Next i
21: End Sub
Navigating Occurrence Model
The flow diagram is presented in Figure 7. Here as well, you need to use a recursive procedure to visit all components in a Product.
Again, you start with obtaining the VPMRootOccurrence object, which is the Product’s root. From there, you start iterating over its VPMOccurrences collection. For each VPMOccurrence in the collection, you obtain its VPMInstance and VPMReference if you need to work with those, and keep looping through its own VPMOccurrences collection.
Figure 7
The sample code is shown below.
01: Sub CATMain()
' Product Root Occurrence
02: Dim oEditor As Editor
03: Set oEditor = CATIA.ActiveEditor
04: Dim oPLMProductService As PLMProductService
05: Set oPLMProductService = oEditor.GetService("PLMProductService")
06: Dim oRootOcc As VPMRootOccurrence
07: Set oRootOcc = oPLMProductService.RootOccurrence
' Start going through its child-occurrences
08: NavigateOccurenceStructure oRootOcc.Occurrences
09: End Sub
10: Sub NavigateOccurenceStructure(cOccurrences As VPMOccurrences)
' Loop through the collection of occurrences
11: Dim i As Integer
12: For i = 1 To cOccurrences.Count
' get the i-th Occurence
13: Dim oOccurence As VPMOccurrence
14: Set oOccurence = cOccurrences.Item(i)
' get VPMInstance and VPMReference, if you need to work with those
15: Dim oVPMInst As VPMInstance
16: Set oVPMInst = oOccurence.InstanceOccurrenceOf()
17: Dim oVPMRef As VPMReference
18: Set oVPMRef = oVPMInst.ReferenceInstanceOf()
'... put your code here to work the instance and/or reference
' Recursively, go through its child-occurrences
19: NavigateOccurenceStructure oOccurence.Occurrences
20: Next i
21: End Sub
Should you use the Occurrence model or the Instance/Reference model if you want to visit each component in the Product? It doesn’t seem to matter, so make your pick.
Building Product Structure
Here’s the bad news.
The earlier (2013x and before) 3DX API had methods to add or remove components to/from the product structure.
In the later 3DX releases, those methods have been removed from the API. Which means – you can’t manipulate the product structure, such as adding new components, in 2014x or later!
Copy/Paste, however, still works. Which means, if the task you want to script could be accomplished using the Copy/Paste functionality, that could be still doable. In a follow-up post in this series, I’ll be explaining how to use the Selection object to Copy/Paste in 3DX.
Searching through Product Structure
You can use the Search method in the Selection object (discussed in one of the follow-up posts) to find specific components in the Product. Keep in mind that the Occurrence model is searched, rather than the Instance/Reference model.
A sample code to search for a component by name is presented below.
' Selection object
01: Dim oSel As Selection
02: Set oSel = CATIA.ActiveEditor.Selection
' Ask for the name to search
03: Dim strName As String
04: strName = InputBox("Enter the 3dPart name to search (can use widcards *)")
' Search
05: oSel.Search "Name='" & strName & "',all"
06: Dim i As Integer
07: For i = 1 To oSel.Count
08: Dim strVName As String
' VPMOccurrence -> this is either 3DPart or PhysicalProduct
09: If oSel.Item(i).Type = "VPMOccurrence" Then
10: Dim oVMPOcc As VPMOccurrence
11: Set oVMPOcc = oSel.Item(i).Value
12: Dim oVPMRef As VPMReference
13: Set oVPMRef = oVMPOcc.InstanceOccurrenceOf().ReferenceInstanceOf()
' No sub-instances -> this is 3DPart
14: If oVPMRef.Instances.Count = 0 Then
‘ this is 3DPart
15: Else
‘ this is PhysicalProduct
16: End If
' VPMRepInstance -> this is 3DShape
17: ElseIf oSel.Item(i).Type = "VPMRepInstance" Then
‘ this is 3DShape
18: End If
19: Next i
Positioning the Components
VPMOccurrence and VPMInstance aggregate the Position object, that can be used for specifying the position of the component within the Product.
You can specify the component’s absolute location either in the parent assembly’s 3D space, using the SetComponents method, or in the root assembly’s 3D space, using the SetAbsComponents method.
Or you can rotate and/or move the component from its current location, using the Apply method.
Both the SetComponents and Apply methods require a 12-component transformation matrix as the input argument, the same as you would use in V5.
Figure 8
Engineering Connections
Engineering Connections (formerly called Constraints in V5) are owned by the VPMReference object.
Assuming the oVPMRef variable points to a VPMReference object, the code to retrieve the EngConnections collection would look as following:
01: Dim cEngCoonections As EngConnections
02: Set cEngConnections = oVPMRef.GetItem(“CATEngConnections”)
The EngConnections collection owns the following methods:
Add – create a new connection
Item – retrieve an existing connection
Remove – delete a connection
Well, that’s pretty much it about the 3DX Product Modeler, I hope it wasn’t too complicated! In my next post, we’ll be working with the Part Modeler and Drawings, so stay tuned.
About the Author
Follow on Linkedin Visit Website More Content by Iouri Apanovitch