diff --git a/src/XCAFDoc/FILES b/src/XCAFDoc/FILES index d491acdb3d..b06717fe96 100755 --- a/src/XCAFDoc/FILES +++ b/src/XCAFDoc/FILES @@ -25,6 +25,8 @@ XCAFDoc_DimTolTool.cxx XCAFDoc_DimTolTool.hxx XCAFDoc_DocumentTool.cxx XCAFDoc_DocumentTool.hxx +XCAFDoc_Editor.cxx +XCAFDoc_Editor.hxx XCAFDoc_GraphNode.cxx XCAFDoc_GraphNode.hxx XCAFDoc_GraphNodeSequence.hxx diff --git a/src/XCAFDoc/XCAFDoc.hxx b/src/XCAFDoc/XCAFDoc.hxx index f8f659d0ff..703e70cfa6 100644 --- a/src/XCAFDoc/XCAFDoc.hxx +++ b/src/XCAFDoc/XCAFDoc.hxx @@ -40,6 +40,7 @@ class XCAFDoc_DimTolTool; class XCAFDoc_LayerTool; class XCAFDoc_MaterialTool; class XCAFDoc_GraphNode; +class XCAFDoc_Editor; //! Definition of general structure of DECAF document @@ -130,6 +131,7 @@ friend class XCAFDoc_DimTolTool; friend class XCAFDoc_LayerTool; friend class XCAFDoc_MaterialTool; friend class XCAFDoc_GraphNode; +friend class XCAFDoc_Editor; }; diff --git a/src/XCAFDoc/XCAFDoc_Editor.cxx b/src/XCAFDoc/XCAFDoc_Editor.cxx new file mode 100644 index 0000000000..89ce9da326 --- /dev/null +++ b/src/XCAFDoc/XCAFDoc_Editor.cxx @@ -0,0 +1,216 @@ +// Created on: 2015-05-14 +// Created by: data exchange team +// Copyright (c) 2000-2015 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Expand +//purpose : Convert Shape(compound) to assambly +//======================================================================= + +Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const TDF_Label& Shape, + const Standard_Boolean recursively) +{ + if(Doc.IsNull() || Shape.IsNull()) + return Standard_False; + + Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(Doc); + Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(Doc); + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(Doc); + + TopoDS_Shape aS = aShapeTool->GetShape(Shape); + if (!aS.IsNull() && aS.ShapeType() == TopAbs_COMPOUND && !aShapeTool->IsAssembly(Shape)) + { + //convert compound to assembly(without attributes) + aShapeTool->Expand(Shape); + //move attrributes + TDF_ChildIterator anIter(Shape, Standard_True); + for(; anIter.More(); anIter.Next()) + { + TDF_Label aChild = anIter.Value(); + + TDF_LabelSequence aLayers; + TDF_LabelSequence aColors; + Handle(TDataStd_Name) aName; + getParams(Doc, aChild, aColors, aLayers, aName); + //get part + TDF_Label aPart; + if(aShapeTool->GetReferredShape(aChild, aPart)) + { + setParams(Doc, aPart, aColors, aLayers, aName); + //remove unnecessary links + TopoDS_Shape aShape = aShapeTool->GetShape(aChild); + if(!aShapeTool->GetShape(aPart.Father()).IsNull()) + { + TopLoc_Location nulloc; + { + aPart.ForgetAttribute(XCAFDoc::ShapeRefGUID()); + if(aShapeTool->GetShape(aPart.Father()).ShapeType() == TopAbs_COMPOUND) + { + aShapeTool->SetShape(aPart, aShape); + } + aPart.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID()); + aChild.ForgetAllAttributes(Standard_False); + } + } + aChild.ForgetAttribute(TNaming_NamedShape::GetID()); + aChild.ForgetAttribute(XCAFDoc_ShapeMapTool::GetID()); + } + } + //if assembly contains compound, expand it recursively(if flag recursively is true) + if(recursively) + { + anIter.Initialize(Shape); + for(; anIter.More(); anIter.Next()) + { + TDF_Label aChild = anIter.Value(); + TDF_Label aPart; + if(aShapeTool->GetReferredShape(aChild, aPart)) + { + Expand(Doc, aPart, recursively); + } + } + } + return Standard_True; + } + return Standard_False; +} + +//======================================================================= +//function : Expand +//purpose : Convert all compounds in Doc to assambly +//======================================================================= + +Standard_Boolean XCAFDoc_Editor::Expand (const TDF_Label& Doc, const Standard_Boolean recursively) +{ + Standard_Boolean result = Standard_False; + TDF_LabelSequence aLabels; + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(Doc); + aShapeTool->GetFreeShapes(aLabels); + for(Standard_Integer i = 1; i <= aLabels.Length(); i++) + { + TopoDS_Shape aS = aShapeTool->GetShape(aLabels(i)); + if (!aS.IsNull() && aS.ShapeType() == TopAbs_COMPOUND && !aShapeTool->IsAssembly(aLabels(i))) + if (Expand(Doc, aLabels(i), recursively)) + { + result = Standard_True; + } + } + return result; +} + +//======================================================================= +//function : getParams +//purpose : Get colors layers and name +//======================================================================= + +Standard_Boolean XCAFDoc_Editor::getParams (const TDF_Label& Doc, const TDF_Label& Label, + TDF_LabelSequence& Colors, TDF_LabelSequence& Layers, + Handle(TDataStd_Name)& Name) +{ + if(Doc.IsNull() || Label.IsNull()) + return Standard_False; + + Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(Doc); + Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(Doc); + + //get colors + XCAFDoc_ColorType aTypeColor = XCAFDoc_ColorGen; + for(;;) + { + TDF_Label aColor; + aColorTool->GetColor(Label, aTypeColor, aColor); + Colors.Append(aColor); + if(aTypeColor == XCAFDoc_ColorCurv) + break; + aTypeColor = (XCAFDoc_ColorType)(aTypeColor + 1); + } + + //get layers + aLayerTool->GetLayers(Label, Layers); + + //get name + Label.FindAttribute(TDataStd_Name::GetID(), Name); + return Standard_True; +} + +//======================================================================= +//function : setParams +//purpose : set colors layers and name +//======================================================================= + +Standard_Boolean XCAFDoc_Editor::setParams (const TDF_Label& Doc, const TDF_Label& Label, + const TDF_LabelSequence& Colors, const TDF_LabelSequence& Layers, + const Handle(TDataStd_Name)& Name) +{ + if(Doc.IsNull() || Label.IsNull()) + return Standard_False; + + Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(Doc); + Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(Doc); + Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(Doc); + + //set layers + if(!Layers.IsEmpty()) + { + for(Standard_Integer i = 1; i <= Layers.Length(); i++) + { + aLayerTool->SetLayer(Label, Layers.Value(i)); + } + } + //set colors + if(!Colors.IsEmpty()) + { + XCAFDoc_ColorType aTypeColor = XCAFDoc_ColorGen; + for(Standard_Integer i = 1; i <= Colors.Length(); i++) + { + if(!Colors.Value(i).IsNull()) + aColorTool->SetColor(Label, Colors.Value(i), aTypeColor); + aTypeColor = (XCAFDoc_ColorType)(aTypeColor + 1); + } + } + //set name + if(!Name.IsNull()) + { + if(Name->Get().Search("=>") < 0) + TDataStd_Name::Set(Label, Name->Get()); + } + else + { + Standard_SStream Stream; + TopoDS_Shape aShape = aShapeTool->GetShape(Label); + TopAbs::Print(aShape.ShapeType(), Stream); + TCollection_AsciiString aName (Stream.str().c_str()); + TDataStd_Name::Set(Label, TCollection_ExtendedString(aName)); + } + return Standard_True; +} \ No newline at end of file diff --git a/src/XCAFDoc/XCAFDoc_Editor.hxx b/src/XCAFDoc/XCAFDoc_Editor.hxx new file mode 100644 index 0000000000..341faeed04 --- /dev/null +++ b/src/XCAFDoc/XCAFDoc_Editor.hxx @@ -0,0 +1,73 @@ +// Created on: 2015-05-14 +// Created by: Ilya Novikov +// Copyright (c) 2000-2015 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_Editor_HeaderFile +#define _XCAFDoc_Editor_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include + + + +//! Tool for edit structure of document. +class XCAFDoc_Editor +{ +public: + + DEFINE_STANDARD_ALLOC + + + //! Convert Shape(compound) to assembly + Standard_EXPORT static Standard_Boolean Expand (const TDF_Label& Doc, const TDF_Label& Shape, const Standard_Boolean recursively = Standard_True) ; + + //! Convert all compounds in Doc to assembly + Standard_EXPORT static Standard_Boolean Expand (const TDF_Label& Doc, const Standard_Boolean recursively = Standard_True) ; + + + + +protected: + + + + + +private: + + + //! Get colors, layers and name from Label + Standard_EXPORT static Standard_Boolean getParams (const TDF_Label& Doc, const TDF_Label& Label, TDF_LabelSequence& Colors, TDF_LabelSequence& Layers, Handle(TDataStd_Name)& Name) ; + + //! Set colors, layers and name from Label + Standard_EXPORT static Standard_Boolean setParams (const TDF_Label& Doc, const TDF_Label& Label, const TDF_LabelSequence& Colors, const TDF_LabelSequence& Layers, const Handle(TDataStd_Name)& Name) ; + + + + +}; + + + + + + + +#endif // _XCAFDoc_Editor_HeaderFile diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx index 05e1a7bfd6..0ce4c13fe7 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.cxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.cxx @@ -1221,20 +1221,44 @@ static void DumpAssembly(Standard_OStream& theDumpLog, const Standard_Integer level, const Standard_Boolean deep) { + TopoDS_Shape S; + XCAFDoc_ShapeTool::GetShape(L, S); + if(S.IsNull()) + return; for (Standard_Integer i=0; iFather()->Label(), Entry); + theDumpLog<<" (refers to "<Get(); + theDumpLog<<" \""<Get()<<"\" "; if (deep) { - TopoDS_Shape S; - XCAFDoc_ShapeTool::GetShape(L, S); theDumpLog<<"("<<*(void**)&S.TShape(); if (! S.Location().IsIdentity()) theDumpLog<<", "<< *(void**)&S.Location(); @@ -1243,18 +1267,12 @@ static void DumpAssembly(Standard_OStream& theDumpLog, theDumpLog<HasFather()) { - if (Node->Father()->Label().HasChild()) - DumpAssembly(theDumpLog, Node->Father()->Label(), level+1, deep); - else { - XCAFDoc_ShapeTool::DumpShape(theDumpLog, Node->Father()->Label(), level+1, deep); - theDumpLog<Father()->Label(), Entry); + theDumpLog<<" (refers to "<Get(); + theDumpLog<<" \""<Get()<<"\" "; if (deep) { theDumpLog<<"("<<*(void**)&S.TShape(); @@ -1796,3 +1833,107 @@ Standard_Boolean XCAFDoc_ShapeTool::FindSHUO (const TDF_LabelSequence& theLabels } return ( !theSHUOAttr.IsNull() ); } + +//======================================================================= +//function : Expand +//purpose : +//======================================================================= + +Standard_Boolean XCAFDoc_ShapeTool::Expand (const TDF_Label& Shape) +{ + if(Shape.IsNull()) + return Standard_False; + + TopoDS_Shape aShape = GetShape(Shape); + if(!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND && !IsAssembly(Shape)) + { + //set assembly attribute + TDataStd_UAttribute::Set ( Shape, XCAFDoc::AssemblyGUID() ); + + TopoDS_Iterator anIter(aShape); + for(; anIter.More(); anIter.Next()) + { + TopoDS_Shape aChildShape = anIter.Value(); + TDF_Label aChild = FindShape(aChildShape, Standard_True); + + TDF_TagSource aTag; + Handle(TDataStd_Name) anAttr; + //make part for child + TDF_Label aPart = aTag.NewChild(Label()); + //make child (if color isn't set or if it is compound) + if(aChild.IsNull()) + { + TopLoc_Location nulloc; + aChild = aTag.NewChild(Shape); + SetShape(aChild, aChildShape); + SetShape(aPart, aChildShape.Located(nulloc)); + } + else + { + //get name + aChild.FindAttribute(TDataStd_Name::GetID(), anAttr); + TopLoc_Location nulloc; + SetShape(aPart, aChildShape.Located(nulloc)); + + } + //set name to part + if(!anAttr.IsNull()) + { + TDataStd_Name::Set(aPart, anAttr->Get()); + } + else + { + Standard_SStream Stream; + TopAbs::Print(aChildShape.ShapeType(), Stream); + TCollection_AsciiString aName (Stream.str().c_str()); + TDataStd_Name::Set(aPart, TCollection_ExtendedString(aName)); + } + + MakeReference(aChild, aPart, aChildShape.Location()); + + makeSubShape(aPart, aChildShape); + } + return Standard_True; + } + return Standard_False; +} + +//======================================================================= +//function : makeSubShape +//purpose : +//======================================================================= + +void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& Part, const TopoDS_Shape& Shape) +{ + TDF_TagSource aTag; + TopoDS_Iterator anIter(Shape); + for(; anIter.More(); anIter.Next()) + { + TopoDS_Shape aChildShape = anIter.Value(); + TDF_Label aChildLabel = FindShape(aChildShape,Standard_True); + if(!aChildLabel.IsNull()) + { + //get name + Handle(TDataStd_Name) anAttr; + aChildLabel.FindAttribute(TDataStd_Name::GetID(), anAttr); + TopLoc_Location nulloc; + //make subshape + TDF_Label aSubLabel = aTag.NewChild(Part); + SetShape(aSubLabel, aChildShape.Located(nulloc)); + //set name to sub shape + if(!anAttr.IsNull()) + { + TDataStd_Name::Set(aSubLabel, anAttr->Get()); + } + else + { + Standard_SStream Stream; + TopAbs::Print(aChildShape.ShapeType(), Stream); + TCollection_AsciiString aName (Stream.str().c_str()); + TDataStd_Name::Set(aSubLabel, TCollection_ExtendedString(aName)); + } + MakeReference(aChildLabel, aSubLabel, aChildShape.Location()); + } + makeSubShape(Part, aChildShape); + } +} \ No newline at end of file diff --git a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx index d61fb3591c..48ebcc3c16 100644 --- a/src/XCAFDoc/XCAFDoc_ShapeTool.hxx +++ b/src/XCAFDoc/XCAFDoc_ShapeTool.hxx @@ -409,7 +409,12 @@ public: //! from upper_usage componet to next_usage //! Returns null attribute if no SHUO found Standard_EXPORT static Standard_Boolean FindSHUO (const TDF_LabelSequence& Labels, Handle(XCAFDoc_GraphNode)& theSHUOAttr); + + //! Convert Shape (compound) to assembly + Standard_EXPORT Standard_Boolean Expand (const TDF_Label& Shape) ; + //! Make subshape for Part from Shape + Standard_EXPORT void makeSubShape (const TDF_Label& Part, const TopoDS_Shape& Shape) ; diff --git a/src/XDEDRAW/XDEDRAW_Common.cxx b/src/XDEDRAW/XDEDRAW_Common.cxx index cff00719ed..ce55357485 100644 --- a/src/XDEDRAW/XDEDRAW_Common.cxx +++ b/src/XDEDRAW/XDEDRAW_Common.cxx @@ -45,6 +45,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #include //============================================================ // Support for several models in DRAW @@ -465,6 +472,53 @@ static Standard_Integer WriteStep (Draw_Interpretor& di, Standard_Integer argc, return 0; } +static Standard_Integer Expand (Draw_Interpretor& di, Standard_Integer argc, const char** argv) +{ + if (argc < 3) { + di<<"Use: "<Main()); + Standard_Boolean recurs = Standard_False; + if(atoi(argv[2]) != 0) + recurs = Standard_True; + + if (argc == 3) + { + if(!XCAFDoc_Editor::Expand(Doc->Main(), recurs)){ + di << "The shape is assembly or not compaund" << "\n"; + return 1; + } + } + else + { + for (Standard_Integer i = 3; i < argc; i++) + { + TDF_Label aLabel; + TDF_Tool::Label(Doc->GetData(), argv[i], aLabel); + if(aLabel.IsNull()){ + TopoDS_Shape aShape; + aShape = DBRep::Get(argv[i]); + aLabel = aShapeTool->FindShape(aShape); + } + + if (!aLabel.IsNull()){ + if(!XCAFDoc_Editor::Expand(Doc->Main(), aLabel, recurs)){ + di << "The shape is assembly or not compaund" << "\n"; + return 1; + } + } + else + { di << argv[i] << " is not a shape" << "\n"; return 1; } + } + } + return 0; +} + void XDEDRAW_Common::InitCommands(Draw_Interpretor& di) { static Standard_Boolean initactor = Standard_False; @@ -482,4 +536,7 @@ void XDEDRAW_Common::InitCommands(Draw_Interpretor& di) { di.Add("XFileSet", "filename: Set the specified file to be the current one",__FILE__, SetCurWS, g); di.Add("XFromShape", "shape: do fromshape command for all the files",__FILE__, FromShape, g); + di.Add("XExpand", "XExpand Doc recursively(0/1) or XExpand Doc recursively(0/1) label1 abel2 ..." + "or XExpand Doc recursively(0/1) shape1 shape2 ...",__FILE__, Expand, g); + } diff --git a/tests/bugs/xde/bug23911 b/tests/bugs/xde/bug23911 index 82bced5a66..83e5f67ee3 100755 --- a/tests/bugs/xde/bug23911 +++ b/tests/bugs/xde/bug23911 @@ -20,7 +20,7 @@ if {[llength ${Log}] < 1} { set status 1 } -if { [regexp "ASSEMBLY" ${Log}] != 1 } { +if { [regexp "INSTANCE" ${Log}] != 1 } { puts "Error: Invalid output of command Xdump" set status 1 } diff --git a/tests/bugs/xde/bug23911_1 b/tests/bugs/xde/bug23911_1 new file mode 100644 index 0000000000..fdf77d1f3f --- /dev/null +++ b/tests/bugs/xde/bug23911_1 @@ -0,0 +1,36 @@ +puts "============" +puts "OCC23911" +puts "============" +puts "" +####################################################################### +# Invalid output of command Xdump +####################################################################### + +XNewDoc D +box b 1 1 1 +ttranslate b 1 0 0 +compound b c +XAddShape D c + +set Log [Xdump D] + +set status 0 + +if {[llength ${Log}] < 1} { + puts "Error: Invalid output of command Xdump" + set status 1 +} + +if { [regexp "ASSEMBLY" ${Log}] != 1 } { + puts "Error: Invalid output of command Xdump" + set status 1 +} + +if { [regexp "SOLID" ${Log}] != 1 } { + puts "Error: Invalid output of command Xdump" + set status 1 +} + +if { ${status} == 0 } { + puts "OK: Good output of command Xdump" +} diff --git a/tests/bugs/xde/bug26216 b/tests/bugs/xde/bug26216 new file mode 100644 index 0000000000..90c92c3202 --- /dev/null +++ b/tests/bugs/xde/bug26216 @@ -0,0 +1,49 @@ +puts "========" +puts "OCC26216" +puts "========" +puts "" +####################################################################### +# Convert compound to assembly +####################################################################### + +pload ALL + +box b1 0 0 0 10 10 10 +box b2 0 0 0 10 10 10 +box b3 0 0 0 10 10 10 +compound b1 b2 b3 c + +XNewDoc D +XAddShape D c 0 +explode c +XSetColor D c_1 1 0 0 +XSetColor D c_2 0 1 0 +XSetColor D c_3 0 0 1 +XExpand D c + +if { [regexp "ASSEMBLY COMPOUND 0:1:1:1 \"COMPOUND\"" [Xdump D]] != 1 } { + puts "ERROR: Structure of document is wrong." +} else { + if { [regexp "RED" [XGetShapeColor D 0:1:1:2]] != 1 } { + puts "ERROR: Structure of document is wrong." + } else { + if { [regexp "GREEN" [XGetShapeColor D 0:1:1:3]] != 1 } { + puts "ERROR: Structure of document is wrong." + } else { + if { [regexp "BLUE1" [XGetShapeColor D 0:1:1:4]] != 1 } { + puts "ERROR: Structure of document is wrong." + } + } + } +} + + + + + + + + + + +