Repository navigation
Problem with entity copying #380
Description
Part of my project involves merging parts of multiple STEP files into one. For now I basically want to merge their product shapes, eventually I will need to add various metadata to these products.
However, even in the most simplified case – taking a single STEP file and copying over only its CARTESIAN_POINT entities (AP242 / AP210e3), I get garbage data in the output roughly every 3-4 runs.
I can try to produce a minimal example but perhaps it will be sufficient to list the core parts:
- The STEP file is opened, similarly to how it is done in the minimal example.
- All of the entities of its instance manager are iterated, and ones whose
EntityName()matches an entry in the whitelist (so just"CARTESIAN_POINT") are replicated usingentity->Replicate()and added to a map mapping the original entity to the new one (std::map<SDAI_Application_instance *, SDAI_Application_instance *>). Keep in mind I will need to make sure entity references are preserved after the STEP merge in the new file, so I need a structure to map the original entities to the new ones. - As far as I can tell,
entity->Replicate()does a "shallow" copy so the attributes point to the exact same memory locations. Because of this I iterate all of the attributes of the entities and adding them to one of two queues. One is for all entity references (std::queue<SDAI_Application_instance *>); the other is for all other types, which I stringify usingattr->asStr()(std::queue<std::string>). - Then I iterate the new replicated entities and their origin's attributes (in the same order as before) so that I can set the attributes of the new entities by reading from the queues in the same order. Entity type attributes read from the first queue, all other read from the second queue and set the attribute value using
attr->StrToVal(strFromQueue). - The remapped entities are collected and all appended into the instance manager of a new STEP file, which then writes the output file.
The entity reference remapping actually seems to work fine, though it sounds more finicky. But in any case, in the minimal case of copying over only CARTESIAN_POINT instances, there are no entity references, since a CARTESIAN_POINT is just:
ENTITY Cartesian_point
SUBTYPE OF (Point);
coordinates : LIST[1:3] OF length_measure;
END_ENTITY;
ENTITY Point
ABSTRACT SUPERTYPE
SUBTYPE OF (Detailed_geometric_model_element);
END_ENTITY;
ENTITY Detailed_geometric_model_element
ABSTRACT SUPERTYPE OF (ONEOF (Direction,
Axis_placement,
Cartesian_transformation_2d,
Cartesian_transformation_3d,
Geometric_placement_operation))
SUBTYPE OF (Representation_item);
END_ENTITY;
ENTITY Representation_item
ABSTRACT SUPERTYPE ;
name : OPTIONAL label;
END_ENTITY;
So #1 = CARTESIAN_POINT('', (0.1, 0.2, 0.3)); is a valid instance.
Am I doing something wrong when restoring the primitive types? Should I do some string copies before adding the result of asStr() or before giving a string to StrToVal()? As far as I can tell, STEPattribute does not store / cache its string representation and asStr() seems to create a string using a std::stringstream.
The concrete case I'm testing is an input file with 256 CARTESIAN_POINTs, all of which have a name either '' or 'Origin' (none of them have $ in their name). When the copy goes wrong, I can see some CARTESIAN_POINTs with $ or even garbage data that is not even valid STEP:
Any ideas? Should I try to reproduce the issue with a minimal example code?
Edit: One more thing – during the execution of the copy, I do a debug trace of the string values that are passed to StrToVal(). They are all either '' or 'Origin', as expected from the source file. This seems to suggest that the string data gets corrupted later.

Activity
AureaNoire commentedon Sep 10, 2018
Oh, maybe I found out why. After I'm done with the "input" file, I do:
I thought the replicated entities would not be associated with the original instance manager, but after removing these three lines I have not seen the garbage data in the output.
So: is there a way I can dissociate the replicated entities from the original instance manager, so I can then delete the instance manager safely?