XCAFDoc_AssemblyItemId.hxx
XCAFDoc_AssemblyItemRef.cxx
XCAFDoc_AssemblyItemRef.hxx
+XCAFDoc_AssemblyIterator.hxx
+XCAFDoc_AssemblyIterator.cxx
+XCAFDoc_AssemblyGraph.hxx
+XCAFDoc_AssemblyGraph.cxx
+XCAFDoc_AssemblyTool.hxx
XCAFDoc_PartId.hxx
XCAFDoc_Area.cxx
XCAFDoc_Area.hxx
--- /dev/null
+// Created on: 2022-05-11
+// Copyright (c) 2022 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Standard_NullObject.hxx>
+#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
+#include <TDataStd_TreeNode.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TDF_Tool.hxx>
+#include <TDocStd_Document.hxx>
+#include <XCAFDoc.hxx>
+#include <XCAFDoc_AssemblyGraph.hxx>
+#include <XCAFDoc_DocumentTool.hxx>
+#include <XCAFDoc_ShapeTool.hxx>
+
+// =======================================================================
+// function : XCAFDoc_AssemblyGraph constructor
+// purpose : Builds an assembly graph from the OCAF document
+// =======================================================================
+
+XCAFDoc_AssemblyGraph::XCAFDoc_AssemblyGraph(const Handle(TDocStd_Document)& theDoc)
+{
+ Standard_NullObject_Raise_if(theDoc.IsNull(), "Null document!");
+
+ myShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc->Main());
+ Standard_NoSuchObject_Raise_if(myShapeTool.IsNull(), "No XCAFDoc_ShapeTool attribute!");
+
+ TDF_Label aDummy;
+ buildGraph(aDummy);
+}
+
+// =======================================================================
+// function : XCAFDoc_AssemblyGraph constructor
+// purpose : Builds an assembly graph from the OCAF label
+// =======================================================================
+
+XCAFDoc_AssemblyGraph::XCAFDoc_AssemblyGraph(const TDF_Label& theLabel)
+{
+ Standard_NullObject_Raise_if(theLabel.IsNull(), "Null label!");
+
+ myShapeTool = XCAFDoc_DocumentTool::ShapeTool(theLabel);
+ Standard_NoSuchObject_Raise_if(myShapeTool.IsNull(), "No XCAFDoc_ShapeTool attribute!");
+
+ buildGraph(theLabel);
+}
+
+// =======================================================================
+// function : IsDirectLink
+// purpose : Checks if one node is the direct child of other one
+// =======================================================================
+
+Standard_Boolean XCAFDoc_AssemblyGraph::IsDirectLink(const Standard_Integer theNode1,
+ const Standard_Integer theNode2) const
+{
+ if (!HasChildren(theNode1))
+ return Standard_False;
+
+ return GetChildren(theNode1).Contains(theNode2);
+}
+
+// =======================================================================
+// function : GetNodeType
+// purpose : Returns node type
+// =======================================================================
+
+XCAFDoc_AssemblyGraph::NodeType
+XCAFDoc_AssemblyGraph::GetNodeType(const Standard_Integer theNode) const
+{
+ const NodeType* typePtr = myNodeTypes.Seek(theNode);
+ if (typePtr == NULL)
+ return NodeType_UNDEFINED;
+
+ return (*typePtr);
+}
+
+// =======================================================================
+// function : NbLinks
+// purpose : Calculates and returns the number of links
+// =======================================================================
+
+Standard_Integer XCAFDoc_AssemblyGraph::NbLinks() const
+{
+ Standard_Integer aNumLinks = 0;
+ for (AdjacencyMap::Iterator it(myAdjacencyMap); it.More(); it.Next())
+ {
+ aNumLinks += it.Value().Extent();
+ }
+ return aNumLinks;
+}
+
+// =======================================================================
+// function : GetUsageOccurrenceQuantity
+// purpose :
+// =======================================================================
+
+Standard_Integer XCAFDoc_AssemblyGraph::NbOccurrences(const Standard_Integer theNode) const
+{
+ const Standard_Integer* aUsageOQPtr = myUsages.Seek(theNode);
+ if (aUsageOQPtr == NULL)
+ return 0;
+
+ return (*aUsageOQPtr);
+}
+
+// =======================================================================
+// function : buildGraph
+// purpose : Builds an assembly graph from the OCAF document
+// =======================================================================
+
+void XCAFDoc_AssemblyGraph::buildGraph(const TDF_Label& theLabel)
+{
+ // We start from those shapes which are "free" in terms of XDE.
+ TDF_LabelSequence aRoots;
+ if (theLabel.IsNull() || (myShapeTool->Label() == theLabel))
+ myShapeTool->GetFreeShapes(aRoots);
+ else
+ aRoots.Append(theLabel);
+
+ for (TDF_LabelSequence::Iterator it(aRoots); it.More(); it.Next())
+ {
+ TDF_Label aLabel = it.Value();
+
+ TDF_Label anOriginal;
+ if (!myShapeTool->GetReferredShape(aLabel, anOriginal))
+ anOriginal = aLabel;
+
+ const Standard_Integer aRootId = addNode(anOriginal, 0);
+ if (aRootId == 0)
+ continue;
+
+ myRoots.Add(aRootId);
+
+ // Add components (the objects nested into the current one).
+ if (myShapeTool->IsAssembly(anOriginal))
+ addComponents(anOriginal, aRootId);
+ }
+}
+
+// =======================================================================
+// function : addComponents
+// purpose : Adds components for the given parent to the graph structure
+// =======================================================================
+
+void XCAFDoc_AssemblyGraph::addComponents(const TDF_Label& theParent,
+ const Standard_Integer theParentId)
+{
+ if (!myShapeTool->IsShape(theParent))
+ {
+ return; // We have to return here in order to prevent iterating by
+ // sub-labels. For parts, sub-labels are used to encode
+ // metadata which is out of interest in conceptual design
+ // intent represented by assembly graph.
+ }
+
+ // Loop over the children (persistent representation of "part-of" relation).
+ for (TDF_ChildIterator anIt(theParent); anIt.More(); anIt.Next())
+ {
+ TDF_Label aComponent = anIt.Value();
+
+ // Add component
+ const Standard_Integer aComponentId = addNode(aComponent, theParentId);
+ if (aComponentId == 0)
+ continue;
+
+ // Protection against deleted empty labels (after expand compounds, for example).
+ Handle(TDataStd_TreeNode) aJumpNode;
+ if (!aComponent.FindAttribute(XCAFDoc::ShapeRefGUID(), aJumpNode))
+ continue;
+
+ // Jump to the referred object (the original).
+ TDF_Label aChildOriginal;
+ if (!aJumpNode.IsNull() && aJumpNode->HasFather())
+ aChildOriginal = aJumpNode->Father()->Label(); // Declaration-level origin.
+
+ if (aChildOriginal.IsNull())
+ continue;
+
+ // Add child
+ const Standard_Integer aChildId = addNode(aChildOriginal, aComponentId);
+ if (aChildId == 0)
+ continue;
+
+ // Process children: add components recursively.
+ addComponents(aChildOriginal, aChildId);
+ }
+}
+
+// =======================================================================
+// function : addNode
+// purpose : Adds node into the graph
+// =======================================================================
+
+Standard_Integer XCAFDoc_AssemblyGraph::addNode(const TDF_Label& theLabel,
+ const Standard_Integer theParentId)
+{
+ NodeType aNodeType = NodeType_UNDEFINED;
+ if (myShapeTool->IsAssembly(theLabel))
+ {
+ if (myShapeTool->IsFree(theLabel))
+ aNodeType = NodeType_AssemblyRoot;
+ else
+ aNodeType = NodeType_Subassembly;
+ }
+ else if (myShapeTool->IsComponent(theLabel))
+ {
+ aNodeType = NodeType_Occurrence;
+ }
+ else if (myShapeTool->IsSubShape(theLabel))
+ {
+ aNodeType = NodeType_Subshape;
+ }
+ else if (myShapeTool->IsSimpleShape(theLabel))
+ {
+ aNodeType = NodeType_Part;
+ }
+
+ if (aNodeType == NodeType_UNDEFINED)
+ return 0;
+
+ // Get ID of the insertion-level node in the abstract assembly graph.
+ const Standard_Integer aChildId = myNodes.Add(theLabel);
+ myNodeTypes.Bind(aChildId, aNodeType);
+
+ if (aNodeType != NodeType_Occurrence)
+ {
+ // Bind usage occurrences.
+ Standard_Integer* aUsageOQPtr = myUsages.ChangeSeek(aChildId);
+ if (aUsageOQPtr == NULL)
+ aUsageOQPtr = myUsages.Bound(aChildId, 1);
+ else
+ ++(*aUsageOQPtr);
+ }
+
+ if (theParentId > 0)
+ {
+ // Add link
+ TColStd_PackedMapOfInteger* aMapPtr = myAdjacencyMap.ChangeSeek(theParentId);
+ if (aMapPtr == NULL)
+ aMapPtr = myAdjacencyMap.Bound(theParentId, TColStd_PackedMapOfInteger());
+
+ (*aMapPtr).Add(aChildId);
+ }
+
+ return aChildId;
+}
+
+// =======================================================================
+// function : Iterator constructor
+// purpose : Iteration starts from the specifid node.
+// =======================================================================
+
+XCAFDoc_AssemblyGraph::Iterator::Iterator(const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ const Standard_Integer theNode)
+{
+ Standard_NullObject_Raise_if(theGraph.IsNull(), "Null assembly graph!");
+ Standard_NullObject_Raise_if(theNode < 1, "Node ID must be positive one-based integer!");
+
+ myGraph = theGraph;
+ myCurrentIndex = theNode;
+}
--- /dev/null
+// Created on: 2022-05-11
+// Copyright (c) 2022 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _XCAFDoc_AssemblyGraph_HeaderFile
+#define _XCAFDoc_AssemblyGraph_HeaderFile
+
+#include <NCollection_DataMap.hxx>
+#include <NCollection_IndexedMap.hxx>
+#include <Standard.hxx>
+#include <Standard_Type.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <TColStd_PackedMapOfInteger.hxx>
+#include <TDF_LabelIndexedMap.hxx>
+
+class TDF_Label;
+class TDocStd_Document;
+class XCAFDoc_ShapeTool;
+
+class XCAFDoc_AssemblyGraph;
+DEFINE_STANDARD_HANDLE(XCAFDoc_AssemblyGraph, Standard_Transient)
+
+// Assembly graph.
+class XCAFDoc_AssemblyGraph : public Standard_Transient
+{
+public:
+
+ //! \brief Type of the graph node.
+ enum NodeType
+ {
+ NodeType_UNDEFINED = 0, //!< Undefined node type.
+ NodeType_AssemblyRoot, //!< Root node.
+ NodeType_Subassembly, //!< Intermediate node.
+ NodeType_Occurrence, //!< Assembly/part occurrence node.
+ NodeType_Part, //!< Leaf node to represent parts.
+ NodeType_Subshape //!< Subshape node.
+ };
+
+ //! \brief Type definition for graph adjacency matrix.
+ //! This is how parent-component links are realized in the assembly graph.
+ typedef NCollection_DataMap<Standard_Integer, TColStd_PackedMapOfInteger> AdjacencyMap;
+
+public:
+
+ //! \brief Graph iterator.
+ class Iterator
+ {
+ public:
+
+ //! \brief Accepting the assembly graph and starting node to iterate.
+ //! Iteration starts from the specified node.
+ //! \param [in] theGraph - assembly graph to iterate.
+ //! \param [in] theNode - graph node ID.
+ Standard_EXPORT Iterator(const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ const Standard_Integer theNode = 1);
+
+ //! Checks if there are more graph nodes to iterate.
+ //! \return true/false.
+ Standard_Boolean More() const
+ {
+ return myCurrentIndex <= myGraph->NbNodes();
+ }
+
+ //! \return 1-based ID of the current node.
+ Standard_Integer Current() const
+ {
+ return myCurrentIndex;
+ }
+
+ //! Moves iterator to the next position.
+ void Next()
+ {
+ ++myCurrentIndex;
+ }
+
+ private:
+
+ Handle(XCAFDoc_AssemblyGraph) myGraph; //!< Assembly graph to iterate.
+ Standard_Integer myCurrentIndex; //!< Current 1-based node ID.
+
+ };
+
+public:
+
+ //! \brief Constructs graph from XCAF document.
+ //! Construction of a formal graph will be done immediately.
+ //! \param [in] theDoc - document to iterate.
+ Standard_EXPORT XCAFDoc_AssemblyGraph(const Handle(TDocStd_Document)& theDoc);
+
+ //! \brief Constructs graph from XCAF label.
+ //! Construction of a formal graph will be done immediately. The specified
+ //! label is used as a starting position.
+ //! \param [in] theDoc - document to iterate.
+ //! \param [in] theLabel - starting position.
+ Standard_EXPORT XCAFDoc_AssemblyGraph(const TDF_Label& theLabel);
+
+ //! \return Document shape tool.
+ const Handle(XCAFDoc_ShapeTool)& GetShapeTool() const
+ {
+ return myShapeTool;
+ }
+
+ //! \brief Returns IDs of the root nodes.
+ //! \return IDs of the root nodes.
+ const TColStd_PackedMapOfInteger& GetRoots() const
+ {
+ return myRoots;
+ }
+
+ //! \brief Checks whether the assembly graph contains (n1, n2) directed link.
+ //! \param [in] theNode1 - one-based ID of the first node.
+ //! \param [in] theNode2 - one-based ID of the second node.
+ //! \return true/false.
+ Standard_EXPORT Standard_Boolean IsDirectLink(const Standard_Integer theNode1,
+ const Standard_Integer theNode2) const;
+
+ //! \brief Checks whether direct children exist for the given node.
+ //! \param [in] theNode - one-based node ID.
+ //! \return true/false.
+ Standard_Boolean HasChildren(const Standard_Integer theNode) const
+ {
+ return myAdjacencyMap.IsBound(theNode);
+ }
+
+ //! \brief Returns IDs of child nodes for the given node.
+ //! \param [in] theNode - one-based node ID.
+ //! \return set of child IDs.
+ const TColStd_PackedMapOfInteger& GetChildren(const Standard_Integer theNode) const
+ {
+ return myAdjacencyMap(theNode);
+ }
+
+ //! \brief Returns the node type from \ref NodeType enum.
+ //! \param [in] theNode - one-based node ID.
+ //! \return node type.
+ //! \sa NodeType
+ Standard_EXPORT NodeType GetNodeType(const Standard_Integer theNode) const;
+
+ //! \brief returns object ID by node ID.
+ //! \param [in] theNode - one-based node ID.
+ //! \return persistent ID.
+ const TDF_Label& GetNode(const Standard_Integer theNode) const
+ {
+ return myNodes(theNode);
+ }
+
+ //! \brief Returns the unordered set of graph nodes.
+ //! \return graph nodes.
+ const TDF_LabelIndexedMap& GetNodes() const
+ {
+ return myNodes;
+ }
+
+ //! \brief Returns the number of graph nodes.
+ //! \return number of graph nodes.
+ Standard_Integer NbNodes() const
+ {
+ return myNodes.Extent();
+ }
+
+ //! \brief Returns the collection of graph links in the form of adjacency matrix.
+ //! \return graph links.
+ const AdjacencyMap& GetLinks() const
+ {
+ return myAdjacencyMap;
+ }
+
+ //! \brief Returns the number of graph links.
+ //! \return number of graph links.
+ Standard_EXPORT Standard_Integer NbLinks() const;
+
+ //! Returns quantity of part usage occurrences.
+ //! \param [in] theNode - one-based part ID.
+ //! \return usage occurrence quantity.
+ Standard_EXPORT Standard_Integer NbOccurrences(const Standard_Integer theNode) const;
+
+private:
+
+ //! Builds graph out of OCAF XDE structure.
+ //! \param [in] theLabel - optional starting position.
+ Standard_EXPORT void buildGraph(const TDF_Label& theLabel);
+
+ //! Adds components for the given parent to the graph structure.
+ //! \param [in] theParent - OCAF label of the parent object.
+ //! \param [in] theParentId - ID of the already registered node representing
+ //! the parent object in the assembly graph
+ //! being populated.
+ Standard_EXPORT void addComponents(const TDF_Label& theParent,
+ const Standard_Integer theParentId);
+
+ //! Adds node into the graph.
+ //! \param [in] theLabel - label at insertion level.
+ //! \param [in] theParentId - parent one-based node IDS.
+ //! \return one-based internal ID of the node.
+ Standard_EXPORT Standard_Integer addNode(const TDF_Label& theLabel,
+ const Standard_Integer theParentId);
+
+private:
+
+ Handle(XCAFDoc_ShapeTool) myShapeTool; //!< Document shape tool.
+ TColStd_PackedMapOfInteger myRoots; //!< IDs of the root nodes.
+ TDF_LabelIndexedMap myNodes; //!< Maps assembly/part entries to graph node IDs.
+ AdjacencyMap myAdjacencyMap; //!< "Part-of" relations.
+ NCollection_DataMap<Standard_Integer, NodeType> myNodeTypes; //!< Node types.
+ NCollection_DataMap<Standard_Integer,
+ Standard_Integer> myUsages; //!< Occurrences usage.
+
+};
+
+#endif // _XCAFDoc_AssemblyGraph_HeaderFile
--- /dev/null
+// Created on: 2022-05-11
+// Copyright (c) 2022 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Standard_NullObject.hxx>
+#include <Standard_NoSuchObject.hxx>
+#include <Standard_RangeError.hxx>
+#include <TDF_LabelSequence.hxx>
+#include <TDF_Tool.hxx>
+#include <TDocStd_Document.hxx>
+#include <XCAFDoc.hxx>
+#include <XCAFDoc_AssemblyIterator.hxx>
+#include <XCAFDoc_DocumentTool.hxx>
+#include <XCAFDoc_ShapeTool.hxx>
+
+// =======================================================================
+// function : XCAFDoc_AssemblyIterator constructor
+// purpose : Starts from free shapes
+// =======================================================================
+
+XCAFDoc_AssemblyIterator::XCAFDoc_AssemblyIterator(const Handle(TDocStd_Document)& theDoc,
+ const Standard_Integer theLevel)
+ : myMaxLevel(theLevel)
+ , mySeedLevel(1)
+{
+ Standard_NullObject_Raise_if(theDoc.IsNull(), "Null document!");
+
+ myShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc->Main());
+ Standard_NoSuchObject_Raise_if(myShapeTool.IsNull(), "No XCAFDoc_ShapeTool attribute!");
+
+ Standard_RangeError_Raise_if(myMaxLevel < 0, "Null document!");
+
+ TDF_LabelSequence aRoots;
+ myShapeTool->GetFreeShapes(aRoots);
+
+ AuxAssemblyItem anAuxItem;
+ TColStd_ListOfAsciiString aParentPath;
+ for (TDF_LabelSequence::Iterator anIt(aRoots); anIt.More(); anIt.Next())
+ {
+ createItem(anIt.Value(), aParentPath, anAuxItem);
+ myFringe.Append(anAuxItem);
+ }
+}
+
+// =======================================================================
+// function : XCAFDoc_AssemblyIterator constructor
+// purpose : Starts from the specified root
+// =======================================================================
+
+XCAFDoc_AssemblyIterator::XCAFDoc_AssemblyIterator(const Handle(TDocStd_Document)& theDoc,
+ const XCAFDoc_AssemblyItemId& theRoot,
+ const Standard_Integer theLevel)
+ : myMaxLevel(theLevel)
+ , mySeedLevel(theRoot.GetPath().Size())
+{
+ Standard_NullObject_Raise_if(theDoc.IsNull(), "Null document!");
+
+ myShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc->Main());
+ Standard_NoSuchObject_Raise_if(myShapeTool.IsNull(), "No XCAFDoc_ShapeTool attribute!");
+
+ Standard_NullObject_Raise_if(theRoot.IsNull(), "Null assembly item!");
+
+ Standard_RangeError_Raise_if(myMaxLevel < 0, "Null document!");
+
+ AuxAssemblyItem aSeed;
+ aSeed.myItem = theRoot;
+ TDF_Tool::Label(theDoc->GetData(), theRoot.GetPath().Last(), aSeed.myLabel);
+
+ if (aSeed.myLabel.IsNull())
+ return;
+
+ TDF_Label anOriginal;
+ if (myShapeTool->GetReferredShape(aSeed.myLabel, anOriginal))
+ {
+ if (!myShapeTool->IsAssembly(aSeed.myLabel))
+ {
+ aSeed.myLabel = anOriginal;
+ }
+ else
+ {
+ TCollection_AsciiString aPathStr = theRoot.ToString();
+ Standard_Integer anIndex = aPathStr.SearchFromEnd("/");
+ if (anIndex != -1)
+ {
+ aPathStr.Remove(anIndex, aPathStr.Length() - anIndex + 1);
+ }
+ aSeed.myItem.Init(aPathStr);
+ }
+ }
+
+ myFringe.Append(aSeed);
+}
+
+// =======================================================================
+// function : More
+// purpose : Checks possibility to continue iteration
+// =======================================================================
+
+Standard_Boolean XCAFDoc_AssemblyIterator::More() const
+{
+ return !myFringe.IsEmpty();
+}
+
+// =======================================================================
+// function : Next
+// purpose : Moves to the next position
+// =======================================================================
+
+void XCAFDoc_AssemblyIterator::Next()
+{
+ if (!More())
+ return; // No next item.
+
+ // Pop item
+ AuxAssemblyItem aCurrent = myFringe.Last();
+ myFringe.Remove(myFringe.Size());
+
+ // Check current depth of iteration (root level is 0-level by convention)
+ const int aCurrentDepth = aCurrent.myItem.GetPath().Size() - mySeedLevel;
+
+ if (aCurrentDepth < myMaxLevel)
+ {
+ // If current item is an assembly, then the next items to iterate in
+ // depth-first order are the components of this assembly
+ TDF_LabelSequence aComponents;
+ if (myShapeTool->IsAssembly(aCurrent.myLabel))
+ {
+ myShapeTool->GetComponents(aCurrent.myLabel, aComponents);
+ }
+ else if (myShapeTool->IsComponent(aCurrent.myLabel))
+ {
+ aComponents.Append(aCurrent.myLabel);
+ }
+
+ // Put all labels pending for iteration to the fringe
+ AuxAssemblyItem anAuxItem;
+ for (Standard_Integer l = aComponents.Length(); l >= 1; --l)
+ {
+ TDF_Label aLabel = aComponents(l); // Insertion-level label
+ createItem(aLabel, aCurrent.myItem.GetPath(), anAuxItem);
+
+ // Set item to iterate
+ myFringe.Append(anAuxItem);
+ }
+ }
+}
+
+// =======================================================================
+// function : Current
+// purpose : Returns current assembly item
+// =======================================================================
+
+XCAFDoc_AssemblyItemId XCAFDoc_AssemblyIterator::Current() const
+{
+ return myFringe.Last().myItem;
+}
+
+// =======================================================================
+// function : createItem
+// purpose : Makes an assembly item id from the specified label
+// =======================================================================
+
+void XCAFDoc_AssemblyIterator::createItem(const TDF_Label& theLabel,
+ const TColStd_ListOfAsciiString& theParentPath,
+ AuxAssemblyItem& theAuxItem) const
+{
+ TCollection_AsciiString anEntry;
+ TDF_Tool::Entry(theLabel, anEntry);
+
+ TDF_Label anOriginal;
+ if (myShapeTool->GetReferredShape(theLabel, anOriginal))
+ {
+ theAuxItem.myLabel = anOriginal;
+ }
+ else
+ {
+ theAuxItem.myLabel = theLabel;
+ }
+
+ TColStd_ListOfAsciiString aPath = theParentPath;
+ aPath.Append(anEntry);
+ theAuxItem.myItem.Init(aPath);
+}
--- /dev/null
+// Created on: 2022-05-11
+// Copyright (c) 2022 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _XCAFDoc_AssemblyIterator_HeaderFile
+#define _XCAFDoc_AssemblyIterator_HeaderFile
+
+#include <NCollection_Sequence.hxx>
+#include <XCAFDoc_AssemblyItemId.hxx>
+
+class TDF_Label;
+class TDocStd_Document;
+class XCAFDoc_ShapeTool;
+
+//! Iterator in depth along the assembly tree.
+class XCAFDoc_AssemblyIterator
+{
+public:
+
+ //! Constructs iterator starting from assembly roots.
+ //! \param [in] theDoc - document to iterate.
+ //! \param [in, opt] theLevel - max level of hierarchy to reach (INT_MAX is for no limit).
+ Standard_EXPORT XCAFDoc_AssemblyIterator(const Handle(TDocStd_Document)& theDoc,
+ const Standard_Integer theLevel = INT_MAX);
+
+ //! Constructs iterator starting from the specified position in the assembly tree.
+ //! \param [in] theDoc - document to iterate.
+ //! \param [in] theRoot - assembly item to start iterating from.
+ //! \param [in, opt] theLevel - max level of hierarchy to reach (INT_MAX is for no limit).
+ Standard_EXPORT XCAFDoc_AssemblyIterator(const Handle(TDocStd_Document)& theDoc,
+ const XCAFDoc_AssemblyItemId& theRoot,
+ const Standard_Integer theLevel = INT_MAX);
+
+ //! \return true if there is still something to iterate, false -- otherwise.
+ Standard_EXPORT Standard_Boolean More() const;
+
+ //! Moves depth-first iterator to the next position.
+ Standard_EXPORT void Next();
+
+ //! \return current item.
+ Standard_EXPORT XCAFDoc_AssemblyItemId Current() const;
+
+private:
+
+ struct AuxAssemblyItem
+ {
+ TDF_Label myLabel;
+ XCAFDoc_AssemblyItemId myItem;
+ };
+
+ void createItem(const TDF_Label& theLabel, const TColStd_ListOfAsciiString& theParentPath,
+ AuxAssemblyItem& theAuxItem) const;
+
+private:
+
+ Handle(XCAFDoc_ShapeTool) myShapeTool; //!< Document shape tool.
+ NCollection_Sequence<AuxAssemblyItem> myFringe; //!< Items pending for iteration.
+ Standard_Integer myMaxLevel; //!< Limit on max depth of iteration.
+ Standard_Integer mySeedLevel; //!< Level of hierarchy where we start.
+};
+
+#endif // _XCAFDoc_AssemblyIterator_HeaderFile
--- /dev/null
+// Created on: 2022-05-11
+// Copyright (c) 2022 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _XCAFDoc_AssemblyTool_HeaderFile
+#define _XCAFDoc_AssemblyTool_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_NullObject.hxx>
+#include <Standard_Type.hxx>
+#include <XCAFDoc_AssemblyIterator.hxx>
+#include <XCAFDoc_AssemblyGraph.hxx>
+
+class TDocStd_Document;
+class XCAFDoc_ShapeTool;
+
+//! Provides generic methods for traversing assembly tree and graph
+class XCAFDoc_AssemblyTool
+{
+public:
+
+ //! \brief Generic method for traversing assembly tree.
+ //! Performs in-depth traversing of the assembly tree and calls
+ //! user defined function for each assembly tree node.
+ //! User function takes single argument of XCAFDoc_AssemblyItemId type
+ //! and returns true/false to continue/break.
+ //! ~~~~~{.cpp}
+ //! Standard_Boolean Print(const XCAFDoc_AssemblyItemId& theItem)
+ //! {
+ //! std::cout << theItem.ToString() << std::endl;
+ //! return Standard_True;
+ //! }
+ //! ~~~~~
+ //! \param [in] theIterator - starting position in the assembly tree.
+ //! \param [in] theFunc - user function called for each assembly tree node.
+ template <typename Func>
+ static void Traverse(XCAFDoc_AssemblyIterator theIterator,
+ Func theFunc)
+ {
+ for (; theIterator.More(); theIterator.Next())
+ {
+ if (!theFunc(theIterator.Current()))
+ break;
+ }
+ }
+
+ //! \brief Generic method for traversing assembly graph.
+ //! Performs in-depth traversing of the assembly graph beginning from root nodes
+ //! and calls user defined function for each assembly graph node accepted
+ //! by the user defined filtering function. Filtering function takes
+ //! the assembly graph passed for traversing, current graph node ID
+ //! and returns true/false to accept/reject node.
+ //! ~~~~~{.cpp}
+ //! Standard_Boolean AcceptPartOnly(const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ //! const Standard_Integer theNode)
+ //! {
+ //! return (theGraph->GetNodeType(theNode) == XCAFDoc_AssemblyGraph::NodeType_Part);
+ //! }
+ //! ~~~~~
+ //! User function theFunc takes the assembly graph passed for traversing, current
+ //! graph node ID and returns true/false to continue/break.
+ //! \param [in] theGraph - assembly graph.
+ //! \param [in] theFilter - user filtering function called for each assembly graph node.
+ //! \param [in] theFunc - user function called for accepted assembly graph node.
+ //! \param [in] theNode - starting positive one-based graph node ID.
+ template <typename Func, typename Filter>
+ static void Traverse(const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ Filter theFilter,
+ Func theFunc,
+ const Standard_Integer theNode = 1)
+ {
+ Standard_NullObject_Raise_if(theGraph.IsNull(), "Null assembly graph!");
+
+ for (XCAFDoc_AssemblyGraph::Iterator anIt(theGraph, theNode); anIt.More(); anIt.Next())
+ {
+ const Standard_Integer aN = anIt.Current();
+ if (theFilter(theGraph, aN))
+ {
+ if (!theFunc(theGraph, aN))
+ break;
+ }
+ }
+ }
+
+};
+
+#endif // _XCAFDoc_AssemblyTool_HeaderFile
#include <XCAFDoc_Editor.hxx>
#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_Transform.hxx>
+#include <Message.hxx>
#include <XCAFDoc.hxx>
+#include <XCAFDimTolObjects_DatumObject.hxx>
+#include <XCAFDimTolObjects_DimensionObject.hxx>
+#include <XCAFNoteObjects_NoteObject.hxx>
+#include <XCAFDoc_AssemblyItemRef.hxx>
+#include <XCAFDoc_AssemblyTool.hxx>
+#include <XCAFDoc_Area.hxx>
+#include <XCAFDoc_Centroid.hxx>
#include <XCAFDoc_ColorTool.hxx>
+#include <XCAFDoc_Datum.hxx>
+#include <XCAFDoc_Dimension.hxx>
+#include <XCAFDoc_DimTol.hxx>
+#include <XCAFDoc_DimTolTool.hxx>
#include <XCAFDoc_DocumentTool.hxx>
#include <XCAFDoc_GraphNode.hxx>
#include <XCAFDoc_Location.hxx>
#include <XCAFDoc_LayerTool.hxx>
#include <XCAFDoc_MaterialTool.hxx>
+#include <XCAFDoc_NoteBalloon.hxx>
+#include <XCAFDoc_NoteBinData.hxx>
+#include <XCAFDoc_NoteComment.hxx>
+#include <XCAFDoc_NotesTool.hxx>
#include <XCAFDoc_ShapeMapTool.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#include <XCAFDoc_VisMaterial.hxx>
#include <XCAFDoc_VisMaterialTool.hxx>
+#include <XCAFDoc_Volume.hxx>
#include <TDF_AttributeIterator.hxx>
#include <TDF_ChildIterator.hxx>
#include <TDF_RelocationTable.hxx>
#include <TDF_Tool.hxx>
#include <TDataStd_TreeNode.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <TNaming_Builder.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS_Compound.hxx>
-#include <TNaming_NamedShape.hxx>
//=======================================================================
//function : Expand
}
}
}
+
+//=======================================================================
+//function : rescaleDimensionRefLabels
+//purpose : Applies geometrical scale to dimension's reference shapes
+// not belonging to the assembly graph
+//=======================================================================
+
+static void rescaleDimensionRefLabels(const TDF_LabelSequence& theRefLabels,
+ BRepBuilderAPI_Transform& theBRepTrsf,
+ const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ const TCollection_AsciiString& theEntryDimension)
+{
+ for (TDF_LabelSequence::Iterator anIt(theRefLabels); anIt.More(); anIt.Next())
+ {
+ const TDF_Label& aL = anIt.Value();
+ if (!theGraph->GetNodes().Contains(aL))
+ {
+ Handle(TNaming_NamedShape) aNS;
+ if (aL.FindAttribute(TNaming_NamedShape::GetID(), aNS))
+ {
+ TopoDS_Shape aShape = aNS->Get();
+ theBRepTrsf.Perform(aShape, Standard_True);
+ if (!theBRepTrsf.IsDone())
+ {
+ Standard_SStream aSS;
+ aSS << "Dimmension PMI " << theEntryDimension << " is not scaled.";
+ Message::SendWarning(aSS.str().c_str());
+ }
+ else
+ {
+ TopoDS_Shape aScaledShape = theBRepTrsf.Shape();
+ TNaming_Builder aBuilder(aL);
+ aBuilder.Generated(aShape, aScaledShape);
+ }
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : shouldRescaleAndCheckRefLabels
+//purpose : Checks if all PMI reference shapes belong to the assembly
+// graph. Returns true if at least one reference shape belongs
+// to the assembly graph.
+//=======================================================================
+
+static Standard_Boolean shouldRescaleAndCheckRefLabels(
+ const Handle(TDF_Data)& theData,
+ const TDF_LabelSequence& theRefLabels,
+ const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ Standard_Boolean& theAllInG)
+{
+ theAllInG = Standard_True;
+ Standard_Boolean aShouldRescale = Standard_False;
+ for (TDF_LabelSequence::Iterator anIt1(theRefLabels); anIt1.More(); anIt1.Next())
+ {
+ const TDF_Label& aL = anIt1.Value();
+ if (theGraph->GetNodes().Contains(aL))
+ {
+ aShouldRescale = Standard_True;
+ }
+ else
+ {
+ Handle(XCAFDoc_AssemblyItemRef) anItemRefAttr;
+ if (!aL.FindAttribute(XCAFDoc_AssemblyItemRef::GetID(), anItemRefAttr))
+ {
+ theAllInG = Standard_False;
+ continue;
+ }
+ const XCAFDoc_AssemblyItemId& anItemId = anItemRefAttr->GetItem();
+ if (anItemId.IsNull())
+ {
+ theAllInG = Standard_False;
+ continue;
+ }
+ TDF_Label aLRef;
+ TDF_Tool::Label(theData, anItemId.GetPath().Last(), aLRef, Standard_False);
+ if (aLRef.IsNull() || !theGraph->GetNodes().Contains(aLRef))
+ {
+ theAllInG = Standard_False;
+ continue;
+ }
+ aShouldRescale = Standard_True;
+ }
+ }
+ return aShouldRescale;
+}
+
+//=======================================================================
+//function : RescaleGeometry
+//purpose : Applies geometrical scale to all assembly parts, component
+// locations and related attributes
+//=======================================================================
+
+Standard_Boolean XCAFDoc_Editor::RescaleGeometry(const TDF_Label& theLabel,
+ const Standard_Real theScaleFactor,
+ const Standard_Boolean theForceIfNotRoot)
+{
+ if (theLabel.IsNull())
+ {
+ Message::SendFail("Null label.");
+ return Standard_False;
+ }
+
+ if (Abs(theScaleFactor) <= gp::Resolution())
+ {
+ Message::SendFail("Scale factor is too small.");
+ return Standard_False;
+ }
+
+ Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theLabel);
+ if (aShapeTool.IsNull())
+ {
+ Message::SendFail("Couldn't find XCAFDoc_ShapeTool attribute.");
+ return Standard_False;
+ }
+
+ if (!theForceIfNotRoot && aShapeTool->Label() != theLabel)
+ {
+ TDF_LabelSequence aFreeLabels;
+ aShapeTool->GetFreeShapes(aFreeLabels);
+ Standard_Boolean aFound = Standard_False;
+ for (TDF_LabelSequence::Iterator anIt(aFreeLabels); anIt.More(); anIt.Next())
+ {
+ if (theLabel == anIt.Value())
+ {
+ aFound = Standard_True;
+ break;
+ }
+ }
+ if (!aFound)
+ {
+ TCollection_AsciiString anEntry;
+ TDF_Tool::Entry(theLabel, anEntry);
+ Standard_SStream aSS;
+ aSS << "Label " << anEntry << " is not a root. Set ForceIfNotRoot true to rescale forcibly.";
+ Message::SendFail(aSS.str().c_str());
+ return Standard_False;
+ }
+ }
+
+ Handle(XCAFDoc_AssemblyGraph) aG = new XCAFDoc_AssemblyGraph(theLabel);
+ if (aG.IsNull())
+ {
+ Message::SendFail("Couldn't create assembly graph.");
+ return Standard_False;
+ }
+
+ Standard_Boolean anIsDone = Standard_True;
+
+ gp_Trsf aTrsf; aTrsf.SetScaleFactor(theScaleFactor);
+ BRepBuilderAPI_Transform aBRepTrsf(aTrsf);
+
+ XCAFDoc_AssemblyTool::Traverse(aG,
+ [](const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ const Standard_Integer theNode) -> Standard_Boolean
+ {
+ const XCAFDoc_AssemblyGraph::NodeType aNodeType = theGraph->GetNodeType(theNode);
+ return (aNodeType == XCAFDoc_AssemblyGraph::NodeType_Part) ||
+ (aNodeType == XCAFDoc_AssemblyGraph::NodeType_Occurrence);
+ },
+ [&](const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ const Standard_Integer theNode) -> Standard_Boolean
+ {
+ const TDF_Label& aLabel = theGraph->GetNode(theNode);
+ const XCAFDoc_AssemblyGraph::NodeType aNodeType = theGraph->GetNodeType(theNode);
+
+ if (aNodeType == XCAFDoc_AssemblyGraph::NodeType_Part)
+ {
+ const TopoDS_Shape aShape = aShapeTool->GetShape(aLabel);
+ aBRepTrsf.Perform(aShape, Standard_True);
+ if (!aBRepTrsf.IsDone())
+ {
+ Standard_SStream aSS;
+ TCollection_AsciiString anEntry;
+ TDF_Tool::Entry(aLabel, anEntry);
+ aSS << "Shape " << anEntry << " is not scaled!";
+ Message::SendFail(aSS.str().c_str());
+ anIsDone = Standard_False;
+ return Standard_False;
+ }
+ TopoDS_Shape aScaledShape = aBRepTrsf.Shape();
+ aShapeTool->SetShape(aLabel, aScaledShape);
+
+ // Update sub-shapes
+ TDF_LabelSequence aSubshapes;
+ aShapeTool->GetSubShapes(aLabel, aSubshapes);
+ for (TDF_LabelSequence::Iterator anItSs(aSubshapes); anItSs.More(); anItSs.Next())
+ {
+ const TDF_Label& aLSs = anItSs.Value();
+ const TopoDS_Shape aSs = aShapeTool->GetShape(aLSs);
+ const TopoDS_Shape aSs1 = aBRepTrsf.ModifiedShape(aSs);
+ aShapeTool->SetShape(aLSs, aSs1);
+ }
+
+ Handle(XCAFDoc_Area) aArea;
+ if (aLabel.FindAttribute(XCAFDoc_Area::GetID(), aArea))
+ {
+ aArea->Set(aArea->Get() * theScaleFactor * theScaleFactor);
+ }
+
+ Handle(XCAFDoc_Centroid) aCentroid;
+ if (aLabel.FindAttribute(XCAFDoc_Centroid::GetID(), aCentroid))
+ {
+ aCentroid->Set(aCentroid->Get().XYZ() * theScaleFactor);
+ }
+
+ Handle(XCAFDoc_Volume) aVolume;
+ if (aLabel.FindAttribute(XCAFDoc_Volume::GetID(), aVolume))
+ {
+ aVolume->Set(aVolume->Get() * theScaleFactor * theScaleFactor * theScaleFactor);
+ }
+ }
+ else if (aNodeType == XCAFDoc_AssemblyGraph::NodeType_Occurrence)
+ {
+ TopLoc_Location aLoc = aShapeTool->GetLocation(aLabel);
+ gp_Trsf aTrsf = aLoc.Transformation();
+ aTrsf.SetTranslationPart(aTrsf.TranslationPart() * theScaleFactor);
+ XCAFDoc_Location::Set(aLabel, aTrsf);
+ }
+
+ return Standard_True;
+ }
+ );
+
+ if (!anIsDone)
+ {
+ return Standard_False;
+ }
+
+ aShapeTool->UpdateAssemblies();
+
+ Handle(XCAFDoc_DimTolTool) aDimTolTool = XCAFDoc_DocumentTool::DimTolTool(theLabel);
+ if (!aDimTolTool.IsNull())
+ {
+ TDF_LabelSequence aDimensions;
+ aDimTolTool->GetDimensionLabels(aDimensions);
+ for (TDF_LabelSequence::Iterator anItD(aDimensions); anItD.More(); anItD.Next())
+ {
+ const TDF_Label& aDimension = anItD.Value();
+
+ TCollection_AsciiString anEntryDimension;
+ TDF_Tool::Entry(aDimension, anEntryDimension);
+
+ Handle(XCAFDoc_Dimension) aDimAttr;
+ if (aDimension.FindAttribute(XCAFDoc_Dimension::GetID(), aDimAttr))
+ {
+ Standard_Boolean aShouldRescale = Standard_False;
+ Standard_Boolean aFirstLInG = Standard_True;
+ Standard_Boolean aSecondLInG = Standard_True;
+ TDF_LabelSequence aShapeLFirst, aShapeLSecond;
+ Standard_Boolean aHasShapeRefs = aDimTolTool->GetRefShapeLabel(aDimension, aShapeLFirst, aShapeLSecond);
+ if (aHasShapeRefs)
+ {
+ aShouldRescale = shouldRescaleAndCheckRefLabels(theLabel.Data(), aShapeLFirst, aG, aFirstLInG) ||
+ shouldRescaleAndCheckRefLabels(theLabel.Data(), aShapeLSecond, aG, aSecondLInG);
+ }
+
+ if (!aShouldRescale)
+ {
+ Standard_SStream aSS;
+ aSS << "Dimension PMI " << anEntryDimension << " is not scaled!";
+ Message::SendWarning(aSS.str().c_str());
+ continue;
+ }
+
+ Handle(XCAFDimTolObjects_DimensionObject) aDimObj = aDimAttr->GetObject();
+
+ if (aDimObj->HasTextPoint())
+ {
+ aDimObj->SetPointTextAttach(aDimObj->GetPointTextAttach().XYZ() * theScaleFactor);
+ }
+
+ if (aDimObj->HasPoint())
+ {
+ aDimObj->SetPoint(aDimObj->GetPoint().XYZ() * theScaleFactor);
+ }
+
+ if (aDimObj->HasPoint2())
+ {
+ aDimObj->SetPoint2(aDimObj->GetPoint2().XYZ() * theScaleFactor);
+ }
+
+ if (aDimObj->HasPlane())
+ {
+ gp_Ax2 aPln = aDimObj->GetPlane();
+ aPln.SetLocation(aPln.Location().XYZ() * theScaleFactor);
+ aDimObj->SetPlane(aPln);
+ }
+
+ Handle(TColStd_HArray1OfReal) aValues = aDimObj->GetValues();
+ if (!aValues.IsNull())
+ {
+ if (!aFirstLInG || !aSecondLInG)
+ {
+ Standard_SStream aSS;
+ aSS << "Dimension PMI " << anEntryDimension << " base shapes do not belong to the rescaled assembly!";
+ Message::SendWarning(aSS.str().c_str());
+ continue;
+ }
+ Standard_Boolean aRescaleOtherValues = Standard_False;
+ TColStd_Array1OfReal& anArray = aValues->ChangeArray1();
+ switch (aDimObj->GetType())
+ {
+ case XCAFDimTolObjects_DimensionType_Location_None:
+ case XCAFDimTolObjects_DimensionType_Location_CurvedDistance:
+ {
+ Standard_SStream aSS;
+ aSS << "Dimension PMI " << anEntryDimension << " is not scaled.";
+ Message::SendWarning(aSS.str().c_str());
+ }
+ break;
+ case XCAFDimTolObjects_DimensionType_Location_LinearDistance:
+ case XCAFDimTolObjects_DimensionType_Location_LinearDistance_FromCenterToOuter:
+ case XCAFDimTolObjects_DimensionType_Location_LinearDistance_FromCenterToInner:
+ case XCAFDimTolObjects_DimensionType_Location_LinearDistance_FromOuterToCenter:
+ case XCAFDimTolObjects_DimensionType_Location_LinearDistance_FromOuterToOuter:
+ case XCAFDimTolObjects_DimensionType_Location_LinearDistance_FromOuterToInner:
+ case XCAFDimTolObjects_DimensionType_Location_LinearDistance_FromInnerToCenter:
+ case XCAFDimTolObjects_DimensionType_Location_LinearDistance_FromInnerToOuter:
+ case XCAFDimTolObjects_DimensionType_Location_LinearDistance_FromInnerToInner:
+ anArray.ChangeFirst() *= theScaleFactor;
+ aRescaleOtherValues = Standard_True;
+ break;
+ case XCAFDimTolObjects_DimensionType_Location_Angular:
+ case XCAFDimTolObjects_DimensionType_Size_Angular:
+ break;
+ case XCAFDimTolObjects_DimensionType_Location_Oriented:
+ case XCAFDimTolObjects_DimensionType_Location_WithPath:
+ {
+ Standard_SStream aSS;
+ aSS << "Dimension PMI " << anEntryDimension << " is not scaled.";
+ Message::SendWarning(aSS.str().c_str());
+ }
+ break;
+ case XCAFDimTolObjects_DimensionType_Size_CurveLength:
+ case XCAFDimTolObjects_DimensionType_Size_Diameter:
+ case XCAFDimTolObjects_DimensionType_Size_SphericalDiameter:
+ case XCAFDimTolObjects_DimensionType_Size_Radius:
+ case XCAFDimTolObjects_DimensionType_Size_SphericalRadius:
+ case XCAFDimTolObjects_DimensionType_Size_ToroidalMinorDiameter:
+ case XCAFDimTolObjects_DimensionType_Size_ToroidalMajorDiameter:
+ case XCAFDimTolObjects_DimensionType_Size_ToroidalMinorRadius:
+ case XCAFDimTolObjects_DimensionType_Size_ToroidalMajorRadius:
+ case XCAFDimTolObjects_DimensionType_Size_ToroidalHighMajorDiameter:
+ case XCAFDimTolObjects_DimensionType_Size_ToroidalLowMajorDiameter:
+ case XCAFDimTolObjects_DimensionType_Size_ToroidalHighMajorRadius:
+ case XCAFDimTolObjects_DimensionType_Size_ToroidalLowMajorRadius:
+ case XCAFDimTolObjects_DimensionType_Size_Thickness:
+ case XCAFDimTolObjects_DimensionType_Size_WithPath:
+ anArray.ChangeFirst() *= theScaleFactor;
+ aRescaleOtherValues = Standard_True;
+ break;
+ case XCAFDimTolObjects_DimensionType_CommonLabel:
+ case XCAFDimTolObjects_DimensionType_DimensionPresentation:
+ {
+ Standard_SStream aSS;
+ aSS << "Dimension PMI " << anEntryDimension << " is not scaled.";
+ Message::SendWarning(aSS.str().c_str());
+ }
+ break;
+ default:
+ {
+ Standard_SStream aSS;
+ aSS << "Dimension PMI of unsupported type " << anEntryDimension << " is not scaled.";
+ Message::SendWarning(aSS.str().c_str());
+ }
+ }
+ rescaleDimensionRefLabels(aShapeLFirst, aBRepTrsf, aG, anEntryDimension);
+ rescaleDimensionRefLabels(aShapeLSecond, aBRepTrsf, aG, anEntryDimension);
+ if (aRescaleOtherValues)
+ {
+ for (Standard_Integer i = anArray.Lower() + 1; i <= anArray.Upper(); ++i)
+ anArray.ChangeValue(i) *= theScaleFactor;
+
+ Handle(TCollection_HAsciiString) aName = aDimObj->GetSemanticName();
+ if (!aName.IsNull())
+ {
+ aName->AssignCat(" (Rescaled to ");
+ Standard_SStream aSS; aSS << aValues->First();
+ aName->AssignCat(aSS.str().c_str());
+ aName->AssignCat(")");
+ }
+ }
+ }
+ else
+ {
+ Standard_SStream aSS;
+ aSS << "Dimension PMI values " << anEntryDimension << " are not scaled.";
+ Message::SendWarning(aSS.str().c_str());
+ }
+
+ aDimAttr->SetObject(aDimObj);
+ }
+ }
+
+ TDF_LabelSequence aDatums;
+ aDimTolTool->GetDatumLabels(aDatums);
+ for (TDF_LabelSequence::Iterator anIt(aDatums); anIt.More(); anIt.Next())
+ {
+ const TDF_Label& aDatum = anIt.Value();
+
+ TCollection_AsciiString anEntryDatum;
+ TDF_Tool::Entry(aDatum, anEntryDatum);
+
+ Handle(XCAFDoc_Datum) aDatumAttr;
+ if (aDatum.FindAttribute(XCAFDoc_Datum::GetID(), aDatumAttr))
+ {
+ Handle(XCAFDimTolObjects_DatumObject) aDatumObj = aDatumAttr->GetObject();
+
+ if (aDatumObj->HasDatumTargetParams())
+ {
+ gp_Ax2 anAxis = aDatumObj->GetDatumTargetAxis();
+ anAxis.SetLocation(anAxis.Location().XYZ() * theScaleFactor);
+ aDatumObj->SetDatumTargetAxis(anAxis);
+ // TODO: Should we rescale target length and width?
+ Standard_SStream aSS;
+ aSS << "Datum PMI target length and width " << anEntryDatum << " are not scaled.";
+ Message::SendWarning(aSS.str().c_str());
+ //aDatumObj->SetDatumTargetLength(aDatumObj->GetDatumTargetLength() * theScaleFactor);
+ //aDatumObj->SetDatumTargetWidth(aDatumObj->GetDatumTargetWidth() * theScaleFactor);
+ }
+
+ if (aDatumObj->HasPointText())
+ {
+ aDatumObj->SetPointTextAttach(aDatumObj->GetPointTextAttach().XYZ() * theScaleFactor);
+ }
+
+ if (aDatumObj->HasPoint())
+ {
+ aDatumObj->SetPoint(aDatumObj->GetPoint().XYZ() * theScaleFactor);
+ }
+
+ if (aDatumObj->HasPlane())
+ {
+ gp_Ax2 aPln = aDatumObj->GetPlane();
+ aPln.SetLocation(aPln.Location().XYZ() * theScaleFactor);
+ aDatumObj->SetPlane(aPln);
+ }
+
+ aDatumAttr->SetObject(aDatumObj);
+ }
+ }
+
+ TDF_LabelSequence aDimTols;
+ aDimTolTool->GetDimTolLabels(aDimTols);
+ for (TDF_LabelSequence::Iterator anIt(aDimTols); anIt.More(); anIt.Next())
+ {
+ const TDF_Label& aDimTol = anIt.Value();
+
+ TCollection_AsciiString anEntryDimTol;
+ TDF_Tool::Entry(aDimTol, anEntryDimTol);
+
+ Handle(XCAFDoc_DimTol) aDimTolAttr;
+ if (aDimTol.FindAttribute(XCAFDoc_DimTol::GetID(), aDimTolAttr))
+ {
+ Standard_SStream aSS;
+ aSS << "DimTol PMI " << anEntryDimTol << " is not scaled.";
+ Message::SendWarning(aSS.str().c_str());
+ }
+ }
+ }
+
+ Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(theLabel);
+ if (!aNotesTool.IsNull())
+ {
+ TDF_LabelSequence aNotes;
+ aNotesTool->GetNotes(aNotes);
+ for (TDF_LabelSequence::Iterator anIt(aNotes); anIt.More(); anIt.Next())
+ {
+ const TDF_Label& aNote = anIt.Value();
+
+ Handle(XCAFDoc_Note) aNoteAttr;
+ if (aNote.FindAttribute(XCAFDoc_NoteComment::GetID(), aNoteAttr) ||
+ aNote.FindAttribute(XCAFDoc_NoteBalloon::GetID(), aNoteAttr) ||
+ aNote.FindAttribute(XCAFDoc_NoteBinData::GetID(), aNoteAttr))
+ {
+ Handle(XCAFNoteObjects_NoteObject) aNoteObj = aNoteAttr->GetObject();
+
+ if (aNoteObj->HasPointText())
+ {
+ aNoteObj->SetPointText(aNoteObj->GetPointText().XYZ() * theScaleFactor);
+ }
+
+ if (aNoteObj->HasPoint())
+ {
+ aNoteObj->SetPoint(aNoteObj->GetPoint().XYZ() * theScaleFactor);
+ }
+
+ if (aNoteObj->HasPlane())
+ {
+ gp_Ax2 aPln = aNoteObj->GetPlane();
+ aPln.SetLocation(aPln.Location().XYZ() * theScaleFactor);
+ aNoteObj->SetPlane(aPln);
+ }
+
+ aNoteAttr->SetObject(aNoteObj);
+ }
+ }
+ }
+
+ return anIsDone;
+}
//! Converts all compounds shapes in the document to assembly
//! @param[in] theDoc input document
- //! @param[in] theShape input shape label
//! @param[in] theRecursively recursively expand a compound subshape
//! @return True if shape successfully expanded
Standard_EXPORT static Standard_Boolean Expand(const TDF_Label& theDoc,
const Standard_Boolean theToCopyVisMaterial = Standard_True,
const Standard_Boolean theToCopyAttributes = Standard_True);
+ //! Applies geometrical scaling to the following assembly components:
+ //! - part geometry
+ //! - sub-assembly/part occurrence location
+ //! - part's centroid, area and volume attributes
+ //! - PMIs (warnings and errors are reported if it is impossible to make changes)
+ //! Normally, should start from a root sub-assembly, but if theForceIfNotRoot true
+ //! scaling will be applied forcibly. If theLabel corresponds to the shape tool
+ //! scaling is applied to the whole assembly.
+ //! @param[in] theLabel starting label
+ //! @param[in] theScaleFactor scale factor, should be positive
+ //! @param[in] theForceIfNotRoot allows scaling of a non root assembly if true,
+ //! otherwise - returns false
+ //! @return true in case of success, otherwise - false.
+ Standard_EXPORT static Standard_Boolean RescaleGeometry(const TDF_Label& theLabel,
+ const Standard_Real theScaleFactor,
+ const Standard_Boolean theForceIfNotRoot = Standard_False);
+
};
#endif // _XCAFDoc_Editor_HeaderFile
#include <AIS_InteractiveObject.hxx>
#include <AIS_Trihedron.hxx>
#include <Aspect_TypeOfLine.hxx>
+#include <BRepBuilderAPI_Transform.hxx>
#include <DBRep.hxx>
#include <DDF_Browser.hxx>
#include <DDocStd.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HSequenceOfExtendedString.hxx>
+#include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
#include <TDataStd_AsciiString.hxx>
#include <TDataStd_ByteArray.hxx>
#include <TDataStd_Comment.hxx>
#include <ViewerTest.hxx>
#include <ViewerTest_AutoUpdater.hxx>
#include <XCAFDoc.hxx>
+#include <XCAFDoc_AssemblyIterator.hxx>
+#include <XCAFDoc_AssemblyGraph.hxx>
+#include <XCAFDoc_AssemblyTool.hxx>
#include <XCAFDoc_Area.hxx>
#include <XCAFDoc_Centroid.hxx>
#include <XCAFDoc_Color.hxx>
#include <XCAFDoc_DimTol.hxx>
#include <XCAFDoc_Dimension.hxx>
#include <XCAFDoc_Datum.hxx>
+#include <XCAFDoc_Editor.hxx>
#include <XCAFDoc_GeomTolerance.hxx>
#include <XCAFDoc_DocumentTool.hxx>
#include <XCAFDoc_GraphNode.hxx>
return 0;
}
+//=======================================================================
+//function : XAssemblyTreeDump
+//purpose : Prints assembly tree structure up to the specified level
+//=======================================================================
+
+static Standard_Integer XDumpAssemblyTree(Draw_Interpretor& di,
+ Standard_Integer argc,
+ const char ** argv)
+{
+ if (argc < 2)
+ {
+ di << "Usage :\n " << argv[0] << " Doc [-root label] [-level l] [-names]\n"
+ << " Doc - document name. \n"
+ << " -root label - starting root label. \n"
+ << " -level l - depth level (infinite by default). \n"
+ << " -names - prints names instead of entries. \n";
+
+ return 1;
+ }
+
+ // get specified document
+ Handle(TDocStd_Document) aDoc;
+ DDocStd::GetDocument(argv[1], aDoc);
+ if (aDoc.IsNull())
+ {
+ di << argv[1] << " is not a document\n";
+ return 1;
+ }
+
+ XCAFDoc_AssemblyItemId aRoot;
+ Standard_Integer aLevel = INT_MAX;
+ Standard_Boolean aPrintNames = Standard_False;
+ for (Standard_Integer iarg = 2; iarg < argc; ++iarg)
+ {
+ if (strcmp(argv[iarg], "-root") == 0)
+ {
+ Standard_ProgramError_Raise_if(iarg + 1 >= argc, "Root is expected!");
+ aRoot.Init(argv[++iarg]);
+ }
+ else if (strcmp(argv[iarg], "-level") == 0)
+ {
+ Standard_ProgramError_Raise_if(iarg + 1 >= argc, "Level is expected!");
+ TCollection_AsciiString anArg = argv[++iarg];
+ Standard_ProgramError_Raise_if(!anArg.IsIntegerValue(), "Integer value is expected!");
+ aLevel = anArg.IntegerValue();
+ }
+ else if (strcmp(argv[iarg], "-names") == 0)
+ {
+ aPrintNames = Standard_True;
+ }
+ }
+
+ Standard_SStream aSS;
+
+ XCAFDoc_AssemblyIterator anIt = aRoot.IsNull() ? XCAFDoc_AssemblyIterator(aDoc, aLevel)
+ : XCAFDoc_AssemblyIterator(aDoc, aRoot, aLevel);
+ XCAFDoc_AssemblyTool::Traverse(anIt, [&](const XCAFDoc_AssemblyItemId& theItem) -> Standard_Boolean
+ {
+ if (aPrintNames)
+ {
+ Standard_Boolean aFirst = Standard_True;
+ for (TColStd_ListOfAsciiString::Iterator anIt(theItem.GetPath()); anIt.More();
+ anIt.Next(), aFirst = Standard_False)
+ {
+ if (!aFirst) aSS << "/";
+ TDF_Label aL;
+ TDF_Tool::Label(aDoc->GetData(), anIt.Value(), aL, Standard_False);
+ if (!aL.IsNull())
+ {
+ TCollection_ExtendedString aName;
+ Handle(TDataStd_Name) aNameAttr;
+ if (aL.FindAttribute(TDataStd_Name::GetID(), aNameAttr))
+ {
+ aName = aNameAttr->Get();
+ aSS << aName;
+ continue;
+ }
+ }
+ aSS << anIt.Value();
+ }
+ aSS << std::endl;
+ }
+ else
+ {
+ aSS << theItem.ToString() << std::endl;
+ }
+ return Standard_True;
+ });
+
+ di << aSS.str().c_str();
+ return 0;
+}
+
+//=======================================================================
+//function : graphNodeTypename
+//purpose : Returns node type name
+//=======================================================================
+
+static
+const char* graphNodeTypename(const XCAFDoc_AssemblyGraph::NodeType theNodeType)
+{
+ switch (theNodeType)
+ {
+ case XCAFDoc_AssemblyGraph::NodeType_AssemblyRoot: return "R";
+ case XCAFDoc_AssemblyGraph::NodeType_Subassembly: return "A";
+ case XCAFDoc_AssemblyGraph::NodeType_Occurrence: return "O";
+ case XCAFDoc_AssemblyGraph::NodeType_Part: return "P";
+ case XCAFDoc_AssemblyGraph::NodeType_Subshape: return "S";
+ default: return "?";
+ }
+}
+
+//=======================================================================
+//function : XAssemblyGraphDump
+//purpose : Prints assembly graph structure
+//=======================================================================
+
+static Standard_Integer XDumpAssemblyGraph(Draw_Interpretor& di,
+ Standard_Integer argc,
+ const char ** argv)
+{
+ if (argc < 2)
+ {
+ di << "Usage :\n " << argv[0] << " Doc [-root label] [-verbose] \n"
+ << " Doc - is the document name. \n"
+ << " -root label - is the optional starting label. \n"
+ << " -names - prints names instead of entries. \n";
+
+ return 1;
+ }
+
+ // get specified document
+ Handle(TDocStd_Document) aDoc;
+ DDocStd::GetDocument(argv[1], aDoc);
+ if (aDoc.IsNull())
+ {
+ di << argv[1] << " is not a document\n";
+ return 1;
+ }
+
+ Standard_Boolean aPrintNames = Standard_False;
+ TDF_Label aLabel = XCAFDoc_DocumentTool::ShapesLabel(aDoc->Main());
+ for (Standard_Integer iarg = 2; iarg < argc; ++iarg)
+ {
+ if (strcmp(argv[iarg], "-root") == 0)
+ {
+ Standard_ProgramError_Raise_if(iarg + 1 >= argc, "Root is expected!");
+ TDF_Tool::Label(aDoc->GetData(), argv[++iarg], aLabel, Standard_False);
+ }
+ else if (strcmp(argv[iarg], "-names") == 0)
+ {
+ aPrintNames = Standard_True;
+ }
+ }
+
+ Handle(XCAFDoc_AssemblyGraph) aG = new XCAFDoc_AssemblyGraph(aLabel);
+
+ Standard_SStream aSS;
+
+ XCAFDoc_AssemblyTool::Traverse(aG,
+ [](const Handle(XCAFDoc_AssemblyGraph)& /*theGraph*/,
+ const Standard_Integer /*theNode*/) -> Standard_Boolean
+ {
+ return Standard_True;
+ },
+ [&](const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ const Standard_Integer theNode) -> Standard_Boolean
+ {
+ const TDF_Label& aLabel = theGraph->GetNode(theNode);
+
+ const XCAFDoc_AssemblyGraph::NodeType aNodeType = theGraph->GetNodeType(theNode);
+
+ TCollection_AsciiString aNodeEntry;
+ if (aPrintNames)
+ {
+ Handle(TDataStd_Name) aNameAttr;
+ if (aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttr))
+ {
+ aNodeEntry.AssignCat("'");
+ aNodeEntry.AssignCat(aNameAttr->Get());
+ aNodeEntry.AssignCat("'");
+ }
+ }
+ if (aNodeEntry.IsEmpty())
+ {
+ TDF_Tool::Entry(aLabel, aNodeEntry);
+ }
+
+ aSS << theNode << " " << graphNodeTypename(aNodeType) << " " << aNodeEntry;
+ const XCAFDoc_AssemblyGraph::AdjacencyMap& anAdjacencyMap = theGraph->GetLinks();
+ const TColStd_PackedMapOfInteger* aLinksPtr = anAdjacencyMap.Seek(theNode);
+ if (aLinksPtr != NULL)
+ {
+ for (TColStd_MapIteratorOfPackedMapOfInteger anIt1(*aLinksPtr); anIt1.More(); anIt1.Next())
+ {
+ aSS << " " << anIt1.Key();
+ }
+ }
+ aSS << std::endl;
+
+ return Standard_True;
+ }
+ );
+
+ di << aSS.str().c_str();
+ return 0;
+}
+
+//=======================================================================
+//function : XDumpNomenclature
+//purpose : Prints number of assembly instances
+//=======================================================================
+
+static Standard_Integer XDumpNomenclature(Draw_Interpretor& di,
+ Standard_Integer argc,
+ const char ** argv)
+{
+ if (argc < 2)
+ {
+ di << "Usage :\n " << argv[0] << " Doc [-names] \n"
+ << " Doc - is the document name. \n"
+ << " -names - prints names instead of entries. \n";
+
+ return 1;
+ }
+
+ // get specified document
+ Handle(TDocStd_Document) aDoc;
+ DDocStd::GetDocument(argv[1], aDoc);
+ if (aDoc.IsNull())
+ {
+ di << argv[1] << " is not a document\n";
+ return 1;
+ }
+
+ Standard_Boolean aPrintNames = Standard_False;
+ for (Standard_Integer iarg = 2; iarg < argc; ++iarg)
+ {
+ if (strcmp(argv[iarg], "-names") == 0)
+ {
+ aPrintNames = Standard_True;
+ }
+ }
+
+ Handle(XCAFDoc_AssemblyGraph) aG = new XCAFDoc_AssemblyGraph(aDoc);
+
+ Standard_SStream aSS;
+
+ XCAFDoc_AssemblyTool::Traverse(aG,
+ [](const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ const Standard_Integer theNode) -> Standard_Boolean
+ {
+ const XCAFDoc_AssemblyGraph::NodeType aNodeType = theGraph->GetNodeType(theNode);
+ return (aNodeType == XCAFDoc_AssemblyGraph::NodeType_AssemblyRoot) ||
+ (aNodeType == XCAFDoc_AssemblyGraph::NodeType_Subassembly) ||
+ (aNodeType == XCAFDoc_AssemblyGraph::NodeType_Part);
+ },
+ [&](const Handle(XCAFDoc_AssemblyGraph)& theGraph,
+ const Standard_Integer theNode) -> Standard_Boolean
+ {
+ const TDF_Label& aLabel = theGraph->GetNode(theNode);
+
+ const XCAFDoc_AssemblyGraph::NodeType aNodeType = theGraph->GetNodeType(theNode);
+
+ TCollection_AsciiString aNodeEntry;
+ if (aPrintNames)
+ {
+ Handle(TDataStd_Name) aNameAttr;
+ if (aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttr))
+ {
+ aNodeEntry.AssignCat("'");
+ aNodeEntry.AssignCat(aNameAttr->Get());
+ aNodeEntry.AssignCat("'");
+ }
+ }
+ if (aNodeEntry.IsEmpty())
+ {
+ TDF_Tool::Entry(aLabel, aNodeEntry);
+ }
+
+ aSS << theNode << " " << graphNodeTypename(aNodeType) << " " << aNodeEntry << " "
+ << theGraph->NbOccurrences(theNode) << std::endl;
+
+ return Standard_True;
+ }
+ );
+
+ di << aSS.str().c_str();
+
+ return 0;
+}
+
+//=======================================================================
+//function : XRescaleGeometry
+//purpose : Applies geometrical scale to all assembly components
+//=======================================================================
+
+static Standard_Integer XRescaleGeometry(Draw_Interpretor& di,
+ Standard_Integer argc,
+ const char ** argv)
+{
+ if (argc < 3)
+ {
+ di << "Usage :\n " << argv[0] << " Doc factor [-root label] [-force]\n"
+ << " Doc - is the document name. \n"
+ << " factor - is the scale factor. \n"
+ << " -root label - is the starting label to apply rescaling. \n"
+ << " -force - forces rescaling even if the starting label\n"
+ << " is not a root. \n";
+
+ return 1;
+ }
+
+ // get specified document
+ Handle(TDocStd_Document) aDoc;
+ DDocStd::GetDocument(argv[1], aDoc);
+ if (aDoc.IsNull())
+ {
+ di << argv[1] << " is not a document\n";
+ return 1;
+ }
+
+ // get scale factor
+ Standard_Real aScaleFactor = Draw::Atof(argv[2]);
+ if (aScaleFactor <= 0)
+ {
+ di << "Scale factor must be positive\n";
+ return 1;
+ }
+
+ Standard_Boolean aForce = Standard_False;
+ TDF_Label aLabel = XCAFDoc_DocumentTool::ShapesLabel(aDoc->Main());
+ for (Standard_Integer iarg = 3; iarg < argc; ++iarg)
+ {
+ if (strcmp(argv[iarg], "-root") == 0)
+ {
+ Standard_ProgramError_Raise_if(iarg + 1 >= argc, "Root is expected!");
+ TDF_Tool::Label(aDoc->GetData(), argv[++iarg], aLabel, Standard_False);
+ }
+ else if (strcmp(argv[iarg], "-force") == 0)
+ {
+ aForce = Standard_True;
+ }
+ }
+
+ if (!XCAFDoc_Editor::RescaleGeometry(aLabel, aScaleFactor, aForce))
+ {
+ di << "Geometry rescale failed\n";
+ return 1;
+ }
+
+ return 0;
+}
+
//=======================================================================
//function : testDoc
//purpose : Method to test destruction of document
__FILE__, XShowFaceBoundary, g);
di.Add ("XTestDoc", "XTestDoc shape", __FILE__, testDoc, g);
+ di.Add("XDumpAssemblyTree",
+ "Doc [-root label] [-level l] [-names]: Iterates through the assembly tree in depth up to the specified level, if any",
+ __FILE__, XDumpAssemblyTree, g);
+ di.Add("XDumpAssemblyGraph",
+ "Doc [-root label] [-names]: Prints assembly graph structure",
+ __FILE__, XDumpAssemblyGraph, g);
+ di.Add("XDumpNomenclature",
+ "Doc [-names]: Prints number of assembly instances",
+ __FILE__, XDumpNomenclature, g);
+ di.Add("XRescaleGeometry",
+ "Doc -scale factor [-root label]: Applies geometrical scale to assembly",
+ __FILE__, XRescaleGeometry, g);
+
// Specialized commands
XDEDRAW_Shapes::InitCommands ( di );
XDEDRAW_Colors::InitCommands ( di );
set DocLayerLabels_First [XGetLayerLabels D_First]
set DocShapeLabels_First [XGetTopLevelShapes D_First]
}
+# Traverse assembly tree
+if {[regexp "TRAVERSE_ASSEMBLY_TREE" $CompareDocumentsMode]} {
+ if {[info exists TRAVERSE_ASSEMBLY_TREE_ARGS]} {
+ set traverse_assembly_tree_result [XDumpAssemblyTree D_First {*}$TRAVERSE_ASSEMBLY_TREE_ARGS]
+ } else {
+ set traverse_assembly_tree_result [XDumpAssemblyTree D_First]
+ }
+ set traverse_assembly_tree_result [string trim $traverse_assembly_tree_result]
+ if {$TRAVERSE_ASSEMBLY_TREE_RESULT != $traverse_assembly_tree_result} {
+ puts "ERROR: Not expected traverse assembly tree result"
+ }
+}
+# Traverse assembly graph
+if {[regexp "TRAVERSE_ASSEMBLY_GRAPH" $CompareDocumentsMode]} {
+ if {[info exists TRAVERSE_ASSEMBLY_GRAPH_ARGS]} {
+ set traverse_assembly_graph_result [XDumpAssemblyGraph D_First {*}$TRAVERSE_ASSEMBLY_GRAPH_ARGS]
+ } else {
+ set traverse_assembly_graph_result [XDumpAssemblyGraph D_First]
+ }
+ set traverse_assembly_graph_result [string trim $traverse_assembly_graph_result]
+ if {$TRAVERSE_ASSEMBLY_GRAPH_RESULT != $traverse_assembly_graph_result} {
+ puts "ERROR: Not expected traverse assembly graph result"
+ }
+}
+# Assembly nomenclature
+if {[regexp "ASSEMBLY_NOMENCLATURE" $CompareDocumentsMode]} {
+ set assembly_nomenclature_result [XDumpNomenclature D_First {*}$ASSEMBLY_NOMENCLATURE_ARGS]
+ set assembly_nomenclature_result [string trim $assembly_nomenclature_result]
+ if {$ASSEMBLY_NOMENCLATURE_RESULT != $assembly_nomenclature_result} {
+ puts "ERROR: Not expected assembly nomenclature result"
+ }
+}
+# Rescale assembly
+if {[regexp "RESCALE_ASSEMBLY" $CompareDocumentsMode]} {
+ if {[info exists RESCALE_ASSEMBLY_CHECK_BOUNDING] && $RESCALE_ASSEMBLY_CHECK_BOUNDING} {
+ XGetOneShape S_First D_First
+ bounding S_First -noTriangulation -save xmin ymin zmin xmax ymax zmax
+ set xmin_First [format "%.2f" [dval xmin]]
+ set ymin_First [format "%.2f" [dval ymin]]
+ set zmin_First [format "%.2f" [dval zmin]]
+ set xmax_First [format "%.2f" [dval xmax]]
+ set ymax_First [format "%.2f" [dval ymax]]
+ set zmax_First [format "%.2f" [dval zmax]]
+ set dx_First [expr $xmax_First - $xmin_First]
+ set dy_First [expr $ymax_First - $ymin_First]
+ set dz_First [expr $zmax_First - $zmin_First]
+ }
+ if {[info exists RESCALE_ASSEMBLY_ARGS]} {
+ XRescaleGeometry D_First $RESCALE_ASSEMBLY_FACTOR {*}$RESCALE_ASSEMBLY_ARGS
+ } else {
+ XRescaleGeometry D_First $RESCALE_ASSEMBLY_FACTOR
+ }
+ if {[info exists RESCALE_ASSEMBLY_CHECK_BOUNDING] && $RESCALE_ASSEMBLY_CHECK_BOUNDING} {
+ XGetOneShape S_Second D_First
+ bounding S_Second -noTriangulation -save xmin ymin zmin xmax ymax zmax
+ set xmin_Second [format "%.2f" [dval xmin]]
+ set ymin_Second [format "%.2f" [dval ymin]]
+ set zmin_Second [format "%.2f" [dval zmin]]
+ set xmax_Second [format "%.2f" [dval xmax]]
+ set ymax_Second [format "%.2f" [dval ymax]]
+ set zmax_Second [format "%.2f" [dval zmax]]
+ set dx_Second [expr $xmax_Second - $xmin_Second]
+ set dy_Second [expr $ymax_Second - $ymin_Second]
+ set dz_Second [expr $zmax_Second - $zmin_Second]
+ set dx_Scale [expr $dx_Second / $dx_First]
+ set dy_Scale [expr $dy_Second / $dy_First]
+ set dz_Scale [expr $dz_Second / $dz_First]
+ if { $dx_Scale != $RESCALE_ASSEMBLY_FACTOR } {
+ puts [format "Error : Compared X scale %f differs from %f specified one" $dx_Scale $RESCALE_ASSEMBLY_FACTOR]
+ }
+ if { $dy_Scale != $RESCALE_ASSEMBLY_FACTOR } {
+ puts [format "Error : Compared Y scale %f differs from %f specified one" $dy_Scale $RESCALE_ASSEMBLY_FACTOR]
+ }
+ if { $dz_Scale != $RESCALE_ASSEMBLY_FACTOR } {
+ puts [format "Error : Compared Z scale %f differs from %f specified one" $dz_Scale $RESCALE_ASSEMBLY_FACTOR]
+ }
+ }
+}
################## WRITING FILE ##################"
###Open temporary file
if { [string compare ${TypeOfFile} ""] == 0 } {
}
}
-XGetOneShape result D_Second
-if {[isdraw result]} {
- checkview -display result -2d -path ${imagedir}/${test_image}.png
+if {![regexp "SKIP_CHECKVIEW" $CompareDocumentsMode]} {
+ XGetOneShape result D_Second
+ if {[isdraw result]} {
+ checkview -display result -2d -path ${imagedir}/${test_image}.png
+ }
}
if {[expr $ErrorCode == 2]} {
009 brep_to_stp_add_CL
010 brep_to_xbf
011 add_ACL_brep
-012 brep_add_CL
\ No newline at end of file
+012 brep_add_CL
+013 traverse
+014 rescale
\ No newline at end of file
--- /dev/null
+
+ReadStep D_First [locate_data_file "as1-oc-214-mat.stp"]
+
+set RESCALE_ASSEMBLY_FACTOR 0.5
+set RESCALE_ASSEMBLY_CHECK_BOUNDING 1
+
+set TypeOfFile ""
+
+set AddToDocument ""
+
+set CompareDocumentsMode "RESCALE_ASSEMBLY"
--- /dev/null
+
+ReadStep D_First [locate_data_file "as1-oc-214-mat.stp"]
+
+set RESCALE_ASSEMBLY_FACTOR 0.5
+set RESCALE_ASSEMBLY_ARGS "-root 0:1:1:9 -force"
+
+set TypeOfFile ""
+
+set AddToDocument ""
+
+set CompareDocumentsMode "RESCALE_ASSEMBLY"
--- /dev/null
+
+ReadStep D_First [locate_data_file "as1_motor.step"]
+
+set RESCALE_ASSEMBLY_FACTOR 0.001
+set RESCALE_ASSEMBLY_ARGS "-root 0:1:1:1"
+
+set TypeOfFile ""
+
+set AddToDocument ""
+
+set CompareDocumentsMode "RESCALE_ASSEMBLY"
--- /dev/null
+
+XOpen [locate_data_file "as1_pmi.xbf"] D_First
+
+set RESCALE_ASSEMBLY_FACTOR 0.5
+set RESCALE_ASSEMBLY_CHECK_BOUNDING 1
+
+set TypeOfFile ""
+
+set AddToDocument ""
+
+set CompareDocumentsMode "RESCALE_ASSEMBLY"
--- /dev/null
+
+ReadStep D_First [locate_data_file "as1-oc-214-mat.stp"]
+
+set TRAVERSE_ASSEMBLY_TREE_ARGS "-names"
+set TRAVERSE_ASSEMBLY_TREE_RESULT "as1
+as1/rod-assembly_1
+as1/rod-assembly_1/nut_1
+as1/rod-assembly_1/nut_2
+as1/rod-assembly_1/rod_1
+as1/l-bracket-assembly_1
+as1/l-bracket-assembly_1/nut-bolt-assembly_1
+as1/l-bracket-assembly_1/nut-bolt-assembly_1/bolt_1
+as1/l-bracket-assembly_1/nut-bolt-assembly_1/nut_3
+as1/l-bracket-assembly_1/nut-bolt-assembly_2
+as1/l-bracket-assembly_1/nut-bolt-assembly_2/bolt_1
+as1/l-bracket-assembly_1/nut-bolt-assembly_2/nut_3
+as1/l-bracket-assembly_1/nut-bolt-assembly_3
+as1/l-bracket-assembly_1/nut-bolt-assembly_3/bolt_1
+as1/l-bracket-assembly_1/nut-bolt-assembly_3/nut_3
+as1/l-bracket-assembly_1/l-bracket_1
+as1/plate_1
+as1/l-bracket-assembly_2
+as1/l-bracket-assembly_2/nut-bolt-assembly_1
+as1/l-bracket-assembly_2/nut-bolt-assembly_1/bolt_1
+as1/l-bracket-assembly_2/nut-bolt-assembly_1/nut_3
+as1/l-bracket-assembly_2/nut-bolt-assembly_2
+as1/l-bracket-assembly_2/nut-bolt-assembly_2/bolt_1
+as1/l-bracket-assembly_2/nut-bolt-assembly_2/nut_3
+as1/l-bracket-assembly_2/nut-bolt-assembly_3
+as1/l-bracket-assembly_2/nut-bolt-assembly_3/bolt_1
+as1/l-bracket-assembly_2/nut-bolt-assembly_3/nut_3
+as1/l-bracket-assembly_2/l-bracket_1"
+
+set TRAVERSE_ASSEMBLY_GRAPH_ARGS "-names"
+set TRAVERSE_ASSEMBLY_GRAPH_RESULT "1 R 'as1' 2 9 20 22
+2 O 'rod-assembly_1' 3
+3 A 'rod-assembly' 4 6 7
+4 O 'nut_1' 5
+5 P 'nut'
+6 O 'nut_2' 5
+7 O 'rod_1' 8
+8 P 'rod'
+9 O 'l-bracket-assembly_1' 10
+10 A 'l-bracket-assembly' 11 16 17 18
+11 O 'nut-bolt-assembly_1' 12
+12 A 'nut-bolt-assembly' 13 15
+13 O 'bolt_1' 14
+14 P 'bolt'
+15 O 'nut_3' 5
+16 O 'nut-bolt-assembly_2' 12
+17 O 'nut-bolt-assembly_3' 12
+18 O 'l-bracket_1' 19
+19 P 'l-bracket'
+20 O 'plate_1' 21
+21 P 'plate'
+22 O 'l-bracket-assembly_2' 10"
+
+set ASSEMBLY_NOMENCLATURE_ARGS "-names"
+set ASSEMBLY_NOMENCLATURE_RESULT "1 R 'as1' 1
+3 A 'rod-assembly' 1
+5 P 'nut' 8
+8 P 'rod' 1
+10 A 'l-bracket-assembly' 2
+12 A 'nut-bolt-assembly' 6
+14 P 'bolt' 6
+19 P 'l-bracket' 2
+21 P 'plate' 1"
+
+set TypeOfFile ""
+
+set AddToDocument ""
+
+set CompareDocumentsMode "TRAVERSE_ASSEMBLY_TREE TRAVERSE_ASSEMBLY_GRAPH ASSEMBLY_NOMENCLATURE SKIP_CHECKVIEW"
--- /dev/null
+
+ReadStep D_First [locate_data_file "as1-oc-214-mat.stp"]
+
+set TRAVERSE_ASSEMBLY_TREE_ARGS "-root 0:1:1:1/0:1:1:2 -names"
+set TRAVERSE_ASSEMBLY_TREE_RESULT "as1/rod-assembly
+as1/rod-assembly/nut_1
+as1/rod-assembly/nut_2
+as1/rod-assembly/rod_1"
+
+set TRAVERSE_ASSEMBLY_GRAPH_ARGS "-root 0:1:1:2 -names"
+set TRAVERSE_ASSEMBLY_GRAPH_RESULT "1 A 'rod-assembly' 2 4 5
+2 O 'nut_1' 3
+3 P 'nut'
+4 O 'nut_2' 3
+5 O 'rod_1' 6
+6 P 'rod'"
+
+set TypeOfFile ""
+
+set AddToDocument ""
+
+set CompareDocumentsMode "TRAVERSE_ASSEMBLY_TREE TRAVERSE_ASSEMBLY_GRAPH SKIP_CHECKVIEW"
--- /dev/null
+
+XOpen [locate_data_file "as1_pmi.xbf"] D_First
+
+set TRAVERSE_ASSEMBLY_GRAPH_ARGS "-names"
+set TRAVERSE_ASSEMBLY_GRAPH_RESULT "1 R 'as1' 2 9 22 25
+2 O 'rod-assembly_1' 3
+3 A 'rod-assembly' 4 6 7
+4 O 'nut_1' 5
+5 P 'nut'
+6 O 'nut_2' 5
+7 O 'rod_1' 8
+8 P 'rod'
+9 O 'l-bracket-assembly_1' 10
+10 A 'l-bracket-assembly' 11 16 17 18
+11 O 'nut-bolt-assembly_1' 12
+12 A 'nut-bolt-assembly' 13 15
+13 O 'bolt_1' 14
+14 P 'bolt'
+15 O 'nut_3' 5
+16 O 'nut-bolt-assembly_2' 12
+17 O 'nut-bolt-assembly_3' 12
+18 O 'l-bracket_1' 19
+19 P 'l-bracket' 20 21
+20 S 0:1:1:8:1
+21 S 0:1:1:8:2
+22 O 'plate_1' 23
+23 P 'plate' 24
+24 S 0:1:1:9:1
+25 O 'l-bracket-assembly_2' 10"
+
+set TypeOfFile ""
+
+set AddToDocument ""
+
+set CompareDocumentsMode "TRAVERSE_ASSEMBLY_GRAPH SKIP_CHECKVIEW"
--- /dev/null
+
+ReadStep D_First [locate_data_file "as1_motor.step"]
+
+set TRAVERSE_ASSEMBLY_TREE_ARGS "-names"
+set TRAVERSE_ASSEMBLY_TREE_RESULT "Product 2
+Product 2/as1
+Product 2/as1/rod-assembly_1
+Product 2/as1/rod-assembly_1/nut_1
+Product 2/as1/rod-assembly_1/nut_2
+Product 2/as1/rod-assembly_1/rod_1
+Product 2/as1/l-bracket-assembly_1
+Product 2/as1/l-bracket-assembly_1/nut-bolt-assembly_1
+Product 2/as1/l-bracket-assembly_1/nut-bolt-assembly_1/bolt_1
+Product 2/as1/l-bracket-assembly_1/nut-bolt-assembly_1/nut_3
+Product 2/as1/l-bracket-assembly_1/nut-bolt-assembly_2
+Product 2/as1/l-bracket-assembly_1/nut-bolt-assembly_2/bolt_1
+Product 2/as1/l-bracket-assembly_1/nut-bolt-assembly_2/nut_3
+Product 2/as1/l-bracket-assembly_1/nut-bolt-assembly_3
+Product 2/as1/l-bracket-assembly_1/nut-bolt-assembly_3/bolt_1
+Product 2/as1/l-bracket-assembly_1/nut-bolt-assembly_3/nut_3
+Product 2/as1/l-bracket-assembly_1/l-bracket_1
+Product 2/as1/plate_1
+Product 2/as1/l-bracket-assembly_2
+Product 2/as1/l-bracket-assembly_2/nut-bolt-assembly_1
+Product 2/as1/l-bracket-assembly_2/nut-bolt-assembly_1/bolt_1
+Product 2/as1/l-bracket-assembly_2/nut-bolt-assembly_1/nut_3
+Product 2/as1/l-bracket-assembly_2/nut-bolt-assembly_2
+Product 2/as1/l-bracket-assembly_2/nut-bolt-assembly_2/bolt_1
+Product 2/as1/l-bracket-assembly_2/nut-bolt-assembly_2/nut_3
+Product 2/as1/l-bracket-assembly_2/nut-bolt-assembly_3
+Product 2/as1/l-bracket-assembly_2/nut-bolt-assembly_3/bolt_1
+Product 2/as1/l-bracket-assembly_2/nut-bolt-assembly_3/nut_3
+Product 2/as1/l-bracket-assembly_2/l-bracket_1
+Product 1
+Product 1/35
+Product 1/35/Item_0
+Product 1/35/Item_0/Item_0
+Product 1/35/Item_1
+Product 1/35/Item_1/Item_0
+Product 1/35/Item_2
+Product 1/35/Item_2/Item_0
+Product 1/35/Item_3
+Product 1/35/Item_3/Item_0
+Product 1/35/Item_4
+Product 1/35/Item_4/Item_0
+Product 1/35/Item_5
+Product 1/35/Item_5/Item_0
+Product 1/35/Item_6
+Product 1/35/Item_6/Item_0
+Product 1/35/Item_7
+Product 1/35/Item_7/Item_0
+Product 1/35/Item_8
+Product 1/35/Item_8/Item_0
+Product 1/35/Item_9
+Product 1/35/Item_9/Item_0
+Product 1/35/Item_10
+Product 1/35/Item_10/Item_0
+Product 1/35/Item_11
+Product 1/35/Item_11/Item_0
+Product 1/35/Item_12
+Product 1/35/Item_12/Item_0
+Product 1/35/Item_13
+Product 1/35/Item_13/Item_0
+Product 1/35/Item_14
+Product 1/35/Item_14/Item_0
+Product 1/35/Item_15
+Product 1/35/Item_15/Item_0
+Product 1/35/Item_16
+Product 1/35/Item_16/Item_0"
+
+set TRAVERSE_ASSEMBLY_GRAPH_ARGS "-names"
+set TRAVERSE_ASSEMBLY_GRAPH_RESULT "1 R 'Product 1' 2
+2 O '35' 3
+3 A 'Product 1.1' 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68
+4 O 'Item_0' 5
+5 A 'Product 1.1.1' 6
+6 O 'Item_0' 7
+7 P 'Product 1.1.1.1'
+8 O 'Item_1' 9
+9 A 'Product 1.1.2' 10
+10 O 'Item_0' 11
+11 P 'Product 1.1.2.1'
+12 O 'Item_2' 13
+13 A 'Product 1.1.3' 14
+14 O 'Item_0' 15
+15 P 'Product 1.1.3.1'
+16 O 'Item_3' 17
+17 A 'Product 1.1.4' 18
+18 O 'Item_0' 19
+19 P 'Product 1.1.4.1'
+20 O 'Item_4' 21
+21 A 'Product 1.1.5' 22
+22 O 'Item_0' 23
+23 P 'Product 1.1.5.1'
+24 O 'Item_5' 25
+25 A 'Product 1.1.6' 26
+26 O 'Item_0' 27
+27 P 'Product 1.1.6.1'
+28 O 'Item_6' 29
+29 A 'Product 1.1.7' 30
+30 O 'Item_0' 31
+31 P 'Product 1.1.7.1'
+32 O 'Item_7' 33
+33 A 'Product 1.1.8' 34
+34 O 'Item_0' 35
+35 P 'Product 1.1.8.1'
+36 O 'Item_8' 37
+37 A 'Product 1.1.9' 38
+38 O 'Item_0' 39
+39 P 'Product 1.1.9.1'
+40 O 'Item_9' 41
+41 A 'Product 1.1.10' 42
+42 O 'Item_0' 43
+43 P 'Product 1.1.10.1'
+44 O 'Item_10' 45
+45 A 'Product 1.1.11' 46
+46 O 'Item_0' 47
+47 P 'Product 1.1.11.1'
+48 O 'Item_11' 49
+49 A 'Product 1.1.12' 50
+50 O 'Item_0' 51
+51 P 'Product 1.1.12.1'
+52 O 'Item_12' 53
+53 A 'Product 1.1.13' 54
+54 O 'Item_0' 55
+55 P 'Product 1.1.13.1'
+56 O 'Item_13' 57
+57 A 'Product 1.1.14' 58
+58 O 'Item_0' 59
+59 P 'Product 1.1.14.1'
+60 O 'Item_14' 61
+61 A 'Product 1.1.15' 62
+62 O 'Item_0' 63
+63 P 'Product 1.1.15.1'
+64 O 'Item_15' 65
+65 A 'Product 1.1.16' 66
+66 O 'Item_0' 67
+67 P 'Product 1.1.16.1'
+68 O 'Item_16' 69
+69 A 'Product 1.1.17' 70
+70 O 'Item_0' 71
+71 P 'Product 1.1.17.1'
+72 R 'Product 2' 73
+73 O 'as1' 74
+74 A 'Product 2.1' 75 82 99 101
+75 O 'rod-assembly_1' 76
+76 A 'rod-assembly' 77 79 80
+77 O 'nut_1' 78
+78 P 'nut'
+79 O 'nut_2' 78
+80 O 'rod_1' 81
+81 P 'rod'
+82 O 'l-bracket-assembly_1' 83
+83 A 'l-bracket-assembly' 84 89 93 97
+84 O 'nut-bolt-assembly_1' 85
+85 A 'nut-bolt-assembly' 86 88
+86 O 'bolt_1' 87
+87 P 'bolt'
+88 O 'nut_3' 78
+89 O 'nut-bolt-assembly_2' 90
+90 A 'nut-bolt-assembly' 91 92
+91 O 'bolt_1' 87
+92 O 'nut_3' 78
+93 O 'nut-bolt-assembly_3' 94
+94 A 'nut-bolt-assembly' 95 96
+95 O 'bolt_1' 87
+96 O 'nut_3' 78
+97 O 'l-bracket_1' 98
+98 P 'l-bracket'
+99 O 'plate_1' 100
+100 P 'plate'
+101 O 'l-bracket-assembly_2' 102
+102 A 'l-bracket-assembly' 103 107 111 115
+103 O 'nut-bolt-assembly_1' 104
+104 A 'nut-bolt-assembly' 105 106
+105 O 'bolt_1' 87
+106 O 'nut_3' 78
+107 O 'nut-bolt-assembly_2' 108
+108 A 'nut-bolt-assembly' 109 110
+109 O 'bolt_1' 87
+110 O 'nut_3' 78
+111 O 'nut-bolt-assembly_3' 112
+112 A 'nut-bolt-assembly' 113 114
+113 O 'bolt_1' 87
+114 O 'nut_3' 78
+115 O 'l-bracket_1' 98"
+
+set TypeOfFile ""
+
+set AddToDocument ""
+
+set CompareDocumentsMode "TRAVERSE_ASSEMBLY_TREE TRAVERSE_ASSEMBLY_GRAPH SKIP_CHECKVIEW"