Implemented base functionality to filter tree with input label to keep.
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_Transform.hxx>
+#include <NCollection_IncAllocator.hxx>
#include <Message.hxx>
#include <XCAFDoc.hxx>
#include <XCAFDimTolObjects_DatumObject.hxx>
return aShouldRescale;
}
+//=======================================================================
+//function : GetChildShapeLabels
+//purpose :
+//=======================================================================
+void XCAFDoc_Editor::GetChildShapeLabels(const TDF_Label& theLabel,
+ TDF_LabelMap& theRelatedLabels)
+{
+ if (theLabel.IsNull() || !XCAFDoc_ShapeTool::IsShape(theLabel))
+ {
+ return;
+ }
+ if (!theRelatedLabels.Add(theLabel))
+ {
+ return; // Label already processed
+ }
+ if (XCAFDoc_ShapeTool::IsAssembly(theLabel) ||
+ XCAFDoc_ShapeTool::IsSimpleShape(theLabel))
+ {
+ for(TDF_ChildIterator aChildIter(theLabel); aChildIter.More(); aChildIter.Next())
+ {
+ const TDF_Label& aChildLabel = aChildIter.Value();
+ GetChildShapeLabels(aChildLabel, theRelatedLabels);
+ }
+ }
+ if (XCAFDoc_ShapeTool::IsReference(theLabel))
+ {
+ TDF_Label aRefLabel;
+ XCAFDoc_ShapeTool::GetReferredShape(theLabel, aRefLabel);
+ GetChildShapeLabels(aRefLabel, theRelatedLabels);
+ }
+}
+
+//=======================================================================
+//function : GetParentShapeLabels
+//purpose :
+//=======================================================================
+void XCAFDoc_Editor::GetParentShapeLabels(const TDF_Label& theLabel,
+ TDF_LabelMap& theRelatedLabels)
+{
+ if (theLabel.IsNull() || !XCAFDoc_ShapeTool::IsShape(theLabel))
+ {
+ return;
+ }
+ if (!theRelatedLabels.Add(theLabel))
+ {
+ return; // Label already processed
+ }
+ if (XCAFDoc_ShapeTool::IsSubShape(theLabel) ||
+ XCAFDoc_ShapeTool::IsComponent(theLabel))
+ {
+ TDF_Label aFatherLabel = theLabel.Father();
+ GetParentShapeLabels(aFatherLabel, theRelatedLabels);
+ }
+ else
+ {
+ TDF_LabelSequence aUsers;
+ XCAFDoc_ShapeTool::GetUsers(theLabel, aUsers);
+ if (!aUsers.IsEmpty())
+ {
+ for (TDF_LabelSequence::Iterator aUserIter(aUsers); aUserIter.More(); aUserIter.Next())
+ {
+ const TDF_Label& aUserLabel = aUserIter.Value();
+ GetParentShapeLabels(aUserLabel, theRelatedLabels);
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : FilterShapeTree
+//purpose :
+//=======================================================================
+bool XCAFDoc_Editor::FilterShapeTree(const Handle(XCAFDoc_ShapeTool)& theShapeTool,
+ const TDF_LabelMap& theLabelsToKeep)
+{
+ if (theLabelsToKeep.IsEmpty())
+ {
+ return false;
+ }
+ Handle(NCollection_BaseAllocator) anAllocator = new NCollection_IncAllocator();
+ TDF_LabelMap aLabelsToKeep (theLabelsToKeep.Size(), anAllocator);
+ for (TDF_LabelMap::Iterator aLabelIter (theLabelsToKeep); aLabelIter.More(); aLabelIter.Next())
+ {
+ GetChildShapeLabels (aLabelIter.Key(), aLabelsToKeep);
+ }
+ TDF_LabelMap aInternalLabels (1, anAllocator);
+ for (TDF_LabelMap::Iterator aLabelIter (theLabelsToKeep); aLabelIter.More(); aLabelIter.Next())
+ {
+ GetParentShapeLabels (aLabelIter.Key(), aInternalLabels);
+ aLabelsToKeep.Unite(aInternalLabels);
+ aInternalLabels.Clear(false);
+ }
+ for(TDF_ChildIterator aLabelIter (theShapeTool->Label(), true); aLabelIter.More(); aLabelIter.Next())
+ {
+ const TDF_Label& aLabel = aLabelIter.Value();
+ if (!aLabelsToKeep.Contains (aLabel))
+ {
+ aLabel.ForgetAllAttributes (Standard_False);
+ }
+ }
+ theShapeTool->UpdateAssemblies();
+ return true;
+}
+
//=======================================================================
//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)
#include <TDataStd_Name.hxx>
#include <TDF_Label.hxx>
#include <TDF_LabelDataMap.hxx>
+#include <TDF_LabelMap.hxx>
#include <TDF_LabelSequence.hxx>
class XCAFDoc_VisMaterial;
const Standard_Boolean theToCopyVisMaterial = Standard_True,
const Standard_Boolean theToCopyAttributes = Standard_True);
+ //! Gets shape labels that has down relation with the input label.
+ //! @param[in] theLabel input label
+ //! @param[out] theRelatedLabels output labels
+ Standard_EXPORT static void GetParentShapeLabels(const TDF_Label& theLabel,
+ TDF_LabelMap& theRelatedLabels);
+
+ //! Gets shape labels that has up relation with the input label.
+ //! @param[in] theLabel input label
+ //! @param[out] theRelatedLabels output labels
+ Standard_EXPORT static void GetChildShapeLabels(const TDF_Label& theLabel,
+ TDF_LabelMap& theRelatedLabels);
+
+ //! Filters original shape tree with keeping structure.
+ //! The result will include the full label hierarchy lower then input labels.
+ //! Any higher hierarchy labels will be filtered to keep only necessary labels.
+ //! All not related shape labels with input will be cleared (all attributes will be removed).
+ //!
+ //! The result impact directly into original document and existed shape labels.
+ //! Attributes related to removed shape can became invalide.
+ //! For example, GDT with relation on removed shape label(s) and without
+ //! attachment point(s) became invalid for visualization.
+ //!
+ //! @param[in] theShapeTool shape tool to extract from
+ //! @param[in] theLabelsToKeep labels to keep
+ //! @return true if the tree was filtered successfully.
+ Standard_EXPORT static bool FilterShapeTree(const Handle(XCAFDoc_ShapeTool)& theShapeTool,
+ const TDF_LabelMap& theLabelsToKeep);
+
//! Applies geometrical scaling to the following assembly components:
//! - part geometry
//! - sub-assembly/part occurrence location
return 0;
}
+//=======================================================================
+//function : Filter
+//purpose :
+//=======================================================================
+static Standard_Integer Filter(Draw_Interpretor& theDI,
+ Standard_Integer theNbArgs,
+ const char** theArgVec)
+{
+ if (theNbArgs < 3)
+ {
+ theDI << "Use: " << theArgVec[0] << "Doc label1 label2 ...\n";
+ return 1;
+ }
+
+ Handle(TDocStd_Document) aDoc;
+ DDocStd::GetDocument(theArgVec[1], aDoc);
+ if (aDoc.IsNull())
+ {
+ theDI << "Error " << theArgVec[1] << " is not a document\n";
+ return 1;
+ }
+ TDF_LabelMap aSrcShapes;
+ for (Standard_Integer anArgInd = 2; anArgInd < theNbArgs; anArgInd++)
+ {
+ TDF_Label aSrcLabel;
+ TDF_Tool::Label(aDoc->GetData(), theArgVec[anArgInd], aSrcLabel);
+ if (aSrcLabel.IsNull() || !XCAFDoc_ShapeTool::IsShape(aSrcLabel))
+ {
+ theDI << "[" << theArgVec[anArgInd] << "] is not valid shape label\n";
+ return 1;
+ }
+ aSrcShapes.Add(aSrcLabel);
+ }
+ if (aSrcShapes.IsEmpty())
+ {
+ theDI << "Error: No Shapes to keep\n";
+ return 1;
+ }
+ Handle(XCAFDoc_ShapeTool) aShTool = XCAFDoc_DocumentTool::ShapeTool(aDoc->Main());
+ if (!XCAFDoc_Editor::FilterShapeTree(aShTool, aSrcShapes))
+ {
+ theDI << "Error: Cannot filter shape tree. Document can be corrupted\n";
+ return 1;
+ }
+ return 0;
+}
+
//=======================================================================
//function : InitCommands
//purpose :
theDI.Add("XExtract", "XExtract dstDoc [dstAssmblSh] srcDoc srcLabel1 srcLabel2 ...\t"
"Extracts given srcLabel1 srcLabel2 ... from srcDoc into given Doc or assembly shape",
__FILE__, Extract, aGroup);
-
+ theDI.Add("XShapeTreeFilter", "XShapeTreeFilter Doc label1 label2 ...\t"
+ "Removes not related labels with input labels from original document. Hierarchical structure is kept",
+ __FILE__, Filter, aGroup);
// Load XSDRAW session for pilot activation
XSDRAW::LoadDraw(theDI);
}
--- /dev/null
+puts "========"
+puts " 0033737: Data Exchange, XCAF - Implementing filter tree functionality"
+puts "========"
+
+pload DE OCAF
+
+Close D_orig D_part1 D_part2 D_part3 D_part4 D_part5 -silent
+
+# get original shape
+Close D_orig -silent
+XOpen [locate_data_file bug28905_as1-oc-214.xbf] D_orig
+XGetOneShape sh_orig D_orig
+
+# any bolt inside assembly
+Close D_orig D_part1 -silent
+XOpen [locate_data_file bug28905_as1-oc-214.xbf] D_part1
+XShapeTreeFilter D_part1 "0:1:1:7"
+XGetOneShape sh1 D_part1
+
+# rod
+Close D_part1 D_part2 -silent
+XOpen [locate_data_file bug28905_as1-oc-214.xbf] D_part2
+XShapeTreeFilter D_part2 "0:1:1:2:3"
+XGetOneShape sh2 D_part2
+
+# plate
+Close D_part2 D_part3 -silent
+XOpen [locate_data_file bug28905_as1-oc-214.xbf] D_part3
+XShapeTreeFilter D_part3 "0:1:1:1:3"
+XGetOneShape sh3 D_part3
+
+# any nuts
+Close D_part3 D_part4 -silent
+XOpen [locate_data_file bug28905_as1-oc-214.xbf] D_part4
+XShapeTreeFilter D_part4 "0:1:1:3"
+XGetOneShape sh4 D_part4
+
+# any nuts
+Close D_part4 D_part5 -silent
+XOpen [locate_data_file bug28905_as1-oc-214.xbf] D_part5
+XShapeTreeFilter D_part5 "0:1:1:8"
+XGetOneShape sh5 D_part5
+
+Close D_part5 -silent
+
+compound sh1 sh2 sh3 sh4 sh5 comp
+
+set props_orig [vprops sh_orig]
+set props_comp [vprops comp]
+
+checkprops sh_orig -equal comp
+
+if { ![regexp {Center of gravity[^0-9=]+= +([-0-9.+eE]+)[^0-9=]+= +([-0-9.+eE]+)[^0-9=]+= +([-0-9.+eE]+)} $props_orig full x_orig y_orig z_orig] } {
+ puts "Error: Problem with properties calculation"
+}
+if { ![regexp {Center of gravity[^0-9=]+= +([-0-9.+eE]+)[^0-9=]+= +([-0-9.+eE]+)[^0-9=]+= +([-0-9.+eE]+)} $props_comp full x_comp y_comp z_comp] } {
+ puts "Error: Problem with properties calculation"
+}
+if {$x_orig != $x_comp || $y_orig != $y_comp || $z_orig != $z_comp} {
+ puts "Error: Different center of gravity"
+}