Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FTA_NonSemanticGDT has no usable properties & FTA_NonSemanticDimension.has_dimension #236

Open
HotWheelsNL opened this issue Jan 9, 2025 · 7 comments
Assignees

Comments

@HotWheelsNL
Copy link

I am trying to capture all requirements from a Catia V5 Part for a work related project. All tolerances are set in 3D using the FTA module. Sadly some are not directly connected to features (NonSemantic). I can access most type however for the FTA_NonSemantic* types I have some problems. I'm a bit lost and can not find any examples that try the same. Can someone tell me if this is a bug or that I am doing something wrong?

Description

I have problems with three distinct classes, I think I am not getting the right Annotation class, but my understanding of package does not go that deep:

FTA_NonSemanticDimension
A dimension with the type FTA_NonSemanticDimension returns a DimensionLimit object while the .has_dimension_limit() returns false. I am not sure if this is a bug or that I am using the wrong interface.

FTA_NonSemanticGDT & FTA_NonSemanticTarget
I cannot get the annotation object to return anything. None of the functions in pycatia/cat_tps_interfaces_annotation returns a result. They all give the same generic error.
I noticed that in pycatia/cat_tps_interfaces_annotations it states that Annotation.item()(CATIAAnnotation interface) is deprecated and that item2 (CATIAAnnotation2 interface) should be used. If I manually try that using 'annotations.item2(x)' I get an AnyObject, which is not the expected Annotation2 object. It does seem that Annotation2 has functions related to the FTA_NonSemanticDimension types.

To Reproduce

FTA_NonSemanticDimension
A dimension with the type FTA_NonSemanticDimension returns a DimensionLimit object while the Annotation.has_dimension_limit() function returns False.

from pycatia import catia # Initialize CATIA application
caa = catia() # Open the desired CATPart document 
document = caa.documents.open('path_to_your_catpart.CATPart') 
part = document.part # Get the annotations 
annotations = part.annotation_sets[0].annotations #Your annotation set
annotation = annotations[0] #Select an annotation with the type FTA_NonSemanticDimension

print(annotation.has_dimension_limit()) #Returns False
print(annotation.dimension_limit() #Returns a filled DimensionLimit object

FTA_NonSemanticGDT

from pycatia import catia # Initialize CATIA application
caa = catia() # Open the desired CATPart document 
document = caa.documents.open('path_to_your_catpart.CATPart') 
part = document.part # Get the annotations 
annotations = part.annotation_sets[0].annotations #Your annotation set
annotation = annotations[0] #Select an annotation with the type FTA_NonSemanticDimension

annotation.datum_simple() #Whichever function I use here it results in the same

The generic error is:

    annotation.datum_simple()
    Traceback (most recent call last():
      File "C:\xxx\xxxx\AppData\Roaming\Python\Python310\site-packages\pycatia\cat_tps_interfaces\annotations.py", line 311, in datum_simple
        return DatumSimple(sef.annotation.DatumSimple())
      File "<COMObject.item>", line 2, in DatumSimple
    pywintypes.com_error:  (-2147352567, 'Exception occured.', (0, 'CATIAAnnotation', 'The method DatumSimple failed', None, 0,-2147467259), None)

Screenshots
Below is a generic picture a found that looks very much like the 3D non semantic tolerance but in 2D instead of 3D.
image

Desktop (please complete the following information):

  • OS: Windows 10
  • CATIA V5 version V5-6R2020
  • pycatia version pycatia 0.8.0

Additional context
I can not attach the CATParts as they are work related, sorry.

@evereux
Copy link
Owner

evereux commented Jan 10, 2025

... but my understanding of package does not go that deep

It's probably deeper than mine. :-)

There are some features of this module I can't test as they were introduced in a later CATIA version than I'm able to test with right now. So, bare with me here ... :-)

The docs state for Annotations.item2:

| o Func Item2(CATVariant iIndex) As AnyObject
|
| Retrieve an Annotation using interface CATIAAnnotation2

It states that it returns an AnyObject in the first line but it should actually return a Annotation2 object?

If I make this change to the development branch so that it does this are you able to test it? The Annotations.item2() class method just fails for me due most likely to a CATIA version issue.

A dimension with the type FTA_NonSemanticDimension returns a DimensionLimit object while the Annotation.has_dimension_limit() function returns False.

I can't reproduce this issue. See example below.

Take a look at the following code sample with regards for checking types and then initialising them.

from pycatia import catia
from pycatia.mec_mod_interfaces.part_document import PartDocument
from pycatia.cat_tps_interfaces.non_semantic_gdt import NonSemanticGDT
from pycatia.cat_tps_interfaces.non_semantic_dimension import NonSemanticDimension

caa = catia()
appliation = caa.application
part_document: PartDocument = appliation.active_document
part = part_document.part
annotation_sets = part.annotation_sets
annotation_set_1 = annotation_sets[0]
annotations = annotation_set_1.annotations

fta_simple_datums = []
fta_non_semantic_gdts = []
fta_non_sematic_dimensions = []

for annotation in annotations:

    # the annotation collection object doesn't assign annotation type to items.
    # so type needs to be checked and type created manually to work with it.
    print(annotation.type)

    if annotation.has_dimension_limit():
        print(annotation.dimension_limit())

    if annotation.type == 'FTA_DatumSimple':
        fta_ds = annotation.datum_simple()
        fta_simple_datums.append(fta_ds)
    if annotation.type == 'FTA_NonSemanticGDT':
        fta_ns_gdt = NonSemanticGDT(annotation.com_object)
        fta_non_semantic_gdts.append(fta_ns_gdt)
    if annotation.type == 'FTA_NonSemanticDimension':
        fta_ns_dim = NonSemanticDimension(annotation.com_object)
        fta_non_sematic_dimensions.append(fta_ns_dim)

# check functionality of annotations
for fta_simple_datum in fta_simple_datums:
    print('__ fta simple datum __')
    print(fta_simple_datum)
    print(fta_simple_datum.label)
    print(fta_simple_datum.targets)
for fta_non_semantic_gdt in fta_non_semantic_gdts:
    print('__ fta non semantic gdt __')
    print(fta_non_semantic_gdt)
    print(fta_non_semantic_gdt.get_2d_annot())
    print(fta_non_semantic_gdt.tps_parallel_on_screen())
for fta_non_sematic_dimension in fta_non_sematic_dimensions:
    print('__ fta non semantic dimension __')
    print(fta_non_sematic_dimension)
    print(fta_non_sematic_dimension.dimension_limit())
    print(fta_non_sematic_dimension.get_2d_annot())
    print(fta_non_sematic_dimension.has_dimension_limit())

@HotWheelsNL
Copy link
Author

Thank you for taking the time to help me.

Of course I am able to test it, I can test upto R32. I tried it myself by changing the AnyObject to an Annotation2 object but importing the Annotation2 resulted in an error about some kind of import loop, which I could not unravel.

I tested your code in R30 and R32.
The FTA_NonSemanticDimension does not print the dimension_limit() in the first for loop, it does in the printing for loop:

C:\Data\VSCode\xxxx> python '.\catiaImport - Copy.py'

FTA_NonSemanticDimension

FTA_DatumSimple

FTA_LinearDimension

DimensionLimit(name="Linear Size.1")

FTA_LinearDimension

DimensionLimit(name="Linear Size.2")

FTA_LinearDimension

DimensionLimit(name="Linear Size.3")

The functions attached to the fta_non_semantic_gdt objects both fail:

...
FTA_Text

FTA_Text

FTA_FlagNote

FTA_NonSemanticDimension

FTA_FlagNote

FTA_Text

FTA_NonSemanticDimension

FTA_NonSemanticGDT

FTA_DatumTarget

FTA_DatumTarget

__ fta simple datum __

DatumSimple(name="Datum Feature.3")

C

Annotations(name="Annotations")

__ fta simple datum __

DatumSimple(name="Datum Feature.4")

B

Annotations(name="Annotations")

__ fta non semantic gdt __

NonSemanticGdt(name="Geometrical Tolerance.1")

Traceback (most recent call last):

  File "C:\Data\VSCode\xxxxx\catiaImport - [Copy.py](http://copy.py/)", line 50, in <module>

    print(fta_non_semantic_gdt.get_2d_annot())

  File "C:\Users\xxxxxx\AppData\Roaming\Python\Python310\site-packages\pycatia\cat_tps_interfaces\non_semantic_gdt.py", line 58, in get_2d_annot

    return DrawingGDT(self.non_semantic_gdt.Get2dAnnot())

  File "C:\Users\xxxxxx\AppData\Roaming\Python\Python310\site-packages\win32com\client\dynamic.py", line 629, in __getattr__

    raise AttributeError(f"{self._username_}.{attr}")

AttributeError: Item.Get2dAnnot

I am not sure if the get_2d_annot function is capable to show a 3d FTA tolerance as 2d, or if it only works if it comes from the drafting workbench. Altough I would expect the variables to be the same. The V5 automation book is quite empty with respect to this class :).

@evereux
Copy link
Owner

evereux commented Jan 10, 2025

For a quick fix for the import loop problem, which may end up being permanent, try doing the import within the class method itself and not at the top of the file. There are a number of places where I could see no option but do this for this project.

So you would have something like:

    def item2(self, i_index: cat_variant) -> 'Annotation2':
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-09-25 14:34:21.593357))
                | o Func Item2(CATVariant iIndex) As AnyObject
                | 
                |     Retrieve an Annotation using interface CATIAAnnotation2

        :param cat_variant i_index:
        :rtype: Annotation2
        """
        from pycatia.cat_tps_interfaces.annotation_2 import Annotation2
        return Annotation2(self.annotations.Item2(i_index))

I'll have another look at these issues over the weekend and see if there's something silly I've done that's an easy fix.

@evereux
Copy link
Owner

evereux commented Jan 10, 2025

Just edited post to correct the return statement. 🙁

@evereux
Copy link
Owner

evereux commented Jan 11, 2025

I've pushed the above change to the development branch. I've also added a number of version checks which won't be interesting for you.

Ultimately though almost all of this I'm unable to test and I can't see any obvious errors I may have made.

The FTA_NonSemanticDimension does not print the dimension_limit() in the first for loop, it does in the printing for loop

I don't understand what you're saying here. If the annotation doesn't have a dimension limit, it won't be printed.

if annotation.has_dimension_limit():
        print(annotation.dimension_limit())

I am not sure if the get_2d_annot function is capable to show a 3d FTA tolerance as 2d, or if it only works if it comes from the drafting workbench. Altough I would expect the variables to be the same. The V5 automation book is quite empty with respect to this class :).

Hmm, you might be right here. NonSemanticGDT.get_2d_annot() returns a DrawingGDT object which Represents a drawing GDT in a drawing view. Does a drawing view also mean a tps view since they are also 2D?

The only way to know for sure I guess is to write something quick and dirty in VBA/CATScript. 🤢

@HotWheelsNL
Copy link
Author

I've pushed the above change to the development branch. I've also added a number of version checks which won't be interesting for you.

I tested the updated code. I do not get any strange errors from the test script or see any strange classes popping up anymore.

I don't understand what you're saying here. If the annotation doesn't have a dimension limit, it won't be printed.

It should not, but in this case it thinks there is no dimension_limits, while there actually is.

    if annotation.type == 'FTA_NonSemanticDimension':
        print('__ fta non semantic dimension test __')
        fta_ns_dim = NonSemanticDimension(annotation.com_object)
        fta_non_sematic_dimensions.append(fta_ns_dim)
        print(annotation.has_dimension_limit())
        print(annotation.dimension_limit().nominal_value)
        print(fta_ns_dim.dimension_limit())
        print('-------------------------------------')

Returns:

    FTA_NonSemanticDimension
    __ fta non semantic dimension test __
    False
    14.6078990305738789
    DimensionLimit(name="Dimension.4")
    -------------------------------------

So the .has_dimension_limit() returns False, but if I am stubborn I do get the values.

I also tried running the original script you send, it results in both errors for both the get_2d_annot function as well as the tps_parallel_on_screen function.

2D annotation:

    __ fta non semantic gdt __
    NonSemanticGdt(name="Geometrical Tolerance.7")
    FTA_NonSemanticGDT
    Traceback (most recent call last):
      File "C:\Data\VSCode\PFDtoARL\catiaImport - Copy.py", line 65, in <module>
        print(fta_non_semantic_gdt.get_2d_annot())
      File "C:Users\xxxxxx\AppData\Roaming\Python\Python310\site_packages\pycatia\cat_tps_interfaces\non_semantic_gdt.py", line 61, in get_2d_annot
        return DrawingGDT(self.non_semantic_gdt.Get2dAnnot())
      File "C:\Users\xxxxxx\AppData\Roaming\Python\Python310\site-packages\win32com\client\dynamic.py", line 629, in __getattr__
        raise AttributeError(f"{self._username_}.{attr}")
    AttributeError: Item.Get2dAnnot

TPS:

    NonSemanticGdt(name="Geometrical Tolerance.1")
    Traceback (most recent call last):
      File "C:\Data\VSCode\PFDtoARL\catiaImport - Copy.py", line 68, in <module>
        print(fta_non_semantic_gdt.tps_parallel_on_screen())
      File "C:\Users\xxxxxxxx\AppData\Roaming\Python\Python310\site-packages\pycatia\cat_tps_interfaces\non_semantic_gdt.py", line 83, in tps_parallel_on_screen
        return TPSParallelOnScreen(self.non_semantic_gdt.TPSParallelOnScreen())
      File "C:\Users\xxxxxxxxxx\AppData\Roaming\Python\Python310\site-packages\win32com\client\dynamic.py", line 629, in __getattr__
        raise AttributeError(f"{self._username_}.{attr}")
    AttributeError: Item.TPSParallelOnScreen

Hmm, you might be right here. NonSemanticGDT.get_2d_annot() returns a DrawingGDT object which Represents a drawing GDT in a drawing view. Does a drawing view also mean a tps view since they are also 2D?

Or does the tps view of a tolerance needs to be converted to an object on a drawing view to get the information out of the tolerance? I am scouring the VBA fora but it only found related questions and no answers. I just found an article that might lead to getting the tolerance id via the annotations class and then using the methods for tps views, but I think that it is a long shot.

@evereux
Copy link
Owner

evereux commented Jan 14, 2025

The inconsistent behaviour of has_dimension_limit appears to be a bug in the CATIA COM interface to me. pycatia is simply a python wrapper to access it.

Until I can get access to a fairly recent version of CATIA V5 for testing there's not much more I can do. Unfortunately, I can't see that happening for several months at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants