Search code examples
pythonvbacomcatia

Catia select a feature from a specific instance in an assembly


Lets say I have an assembly like this:

MainProduct:
-Product1 (Instance of Part1)
-Product2 (Instance of Part2)
-Product3 (Instance of Part2)
-Product4 (Instance of Part3)
...

Now, I want to copy/paste a feature from Product3 into another one.
But I run into problems when selecting the feature programmatically, because there are 2 instances of the part of that feature.

I can't control which feature will be selected by CATIA.ActiveDocument.Selection.Add(myExtractReference)
Catia always selects the feature from Product2 instead of the feature from Product3. So the position of the pasted feature will be wrong!

Does anybody know this problem and has a solution to it?

Edit: The feature reference which I want to copy already exists as a variable because it was newly created (an extract of selected geometry)


Solution

  • I could get help else where. Still want to share my solution. It's written in Python but in VBA its almost the same. The clue is to access CATIA.Selection.Item(1).LeafProduct in order to know where the initial selection was made.

    import win32com.client
    import pycatia
    
    CATIA = win32com.client.dynamic.DumbDispatch('CATIA.Application')
    c_doc = CATIA.ActiveDocument
    c_sel = c_doc.Selection
    c_prod   = c_doc.Product
    
    # New part where the feature should be pasted
    new_prod = c_prod.Products.AddNewComponent("Part", "")
    new_part_doc = new_prod.ReferenceProduct.Parent
    
    # from user selection
    sel_obj = c_sel.Item(1).Value
    
    sel_prod_by_user = c_sel.Item(1).LeafProduct  #  reference to the actual product where the selection was made
    doc_from_sel = sel_prod_by_user.ReferenceProduct.Parent  # part doc from selection
    hb = doc_from_sel.Part.HybridBodies.Add()  # new hybrid body for the extract. will be deleted later on
    extract = doc_from_sel.Part.HybridShapeFactory.AddNewExtract(sel_obj)
    hb.AppendHybridShape(extract)
    doc_from_sel.Part.Update()
    
    # Add the extract to the selection and copy it
    c_sel.Clear()
    c_sel.Add(extract)
    sel_prod_by_catia = c_sel.Item(1).LeafProduct  # reference to the product where Catia makes the selection
    c_sel_copy()  # will call Selection.Copy from VBA. Buggy in Python.
    
    # Paste the extract into the new part in a new hybrid body
    c_sel.Clear()
    new_hb = new_part_doc.Part.HybridBodies.Item(1)
    c_sel.Add(new_hb)
    c_sel.PasteSpecial("CATPrtResultWithOutLink")
    new_part_doc.Part.Update()
    new_extract = new_hb.HybridShapes.Item(new_hb.HybridShapes.Count)
    
    # Redo changes in the part, where the selection was made
    c_sel.Clear()
    c_sel.Add(hb)
    c_sel.Delete()
    
    # Create axis systems from Position object of sel_prd_by_user and sel_prd_by_catia
    prod_list = [sel_prod_by_user, sel_prod_by_catia]
    axs_list = []
    for prod in prod_list:
        pc_pos = pycatia.in_interfaces.position.Position(prod.Position) # conversion to pycata's Position object, necessary
                                                                        # in order to use Position.GetComponents
        ax_comp = pc_pos.get_components()
        axs = new_part_doc.Part.AxisSystems.Add()
        axs.PutOrigin(ax_comp[9:12])
        axs.PutXAxis(ax_comp[0:3])
        axs.PutYAxis(ax_comp[3:6])
        axs.PutZAxis(ax_comp[6:9])
        axs_list.append(axs)
        new_part_doc.Part.Update()
    
    # Translate the extract from axis system derived from sel_prd_by_catia to sel_prd_by_user
    extract_ref = new_part_doc.Part.CreateReferenceFromObject(new_extract)
    tgt_ax_ref = new_part_doc.Part.CreateReferenceFromObject(axs_list[0])
    ref_ax_ref = new_part_doc.Part.CreateReferenceFromObject(axs_list[1])
    new_extract_translated = new_part_doc.Part.HybridShapeFactory.AddNewAxisToAxis(extract_ref, ref_ax_ref, tgt_ax_ref)
    new_hb.AppendHybridShape(new_extract_translated)
    new_part_doc.Part.Update()