Transitioning Macros Part 4: Product Modeler

December 18, 2023 Iouri Apanovitch

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

Iouri Apanovitch

Senior Technical Training Engineer<br><br>As a senior member of the Rand 3D team with a doctorate degree in Finite Element Analysis (FEA) and over 35 years of experience, Iouri provides design, consulting, and training services to those in the aerospace, automotive, electronics, and consumer goods industries. Iouri is a seasoned pro in 3D parametric design and prototyping using knowledge-based engineering methods, and has worked on a wide range of projects including BOM automation, CMM points generation, automated 3D annotation creation, and die tooling automation design. He is also a sought-after instructor and holds the designations of both CATIA Certified Professional (Expert level) and CATIA Certified Instructor.

Follow on Linkedin Visit Website More Content by Iouri Apanovitch
Previous Article
Transitioning Macros Part 3: Services
Transitioning Macros Part 3: Services

What if you want to program an operation that is not related to the type of content you’re working with? In...

Next Article
Transitioning Macros Part 5: Part Modeling & Drafting
Transitioning Macros Part 5: Part Modeling & Drafting

Here we look at Part and the Drafting scripting in 3DX which is very similar to V5.