mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-03 17:56:21 +03:00
0028055: Add UpdateAssemblies() method for top-down update of assembly compounds
- Implement top-down update for assemblies in XCAFDoc_ShapeTool - Get rid of UpdateAssembly() method used for partial (parent-only) update - Adjust STEP and IGES translators to use the top-down update after filling OCAF - Implement XUpdateAssemblies Draw command - Add test cases bug28055_1 and bug28055_2 for component removal and part update - Update XDE documentation to mention the new UpdateAssemblies() method Correction for issue CR28055 Adjusting of test case bugs/fclasses/bug28217
This commit is contained in:
parent
7755fe829e
commit
acc909a893
@ -8910,6 +8910,19 @@ Sets a shape at the indicated label.
|
||||
XSetShape D 0:1:1:3 b
|
||||
~~~~~
|
||||
|
||||
@subsubsection occt_draw_8_6_15 XUpdateAssemblies
|
||||
|
||||
Syntax:
|
||||
~~~~~
|
||||
XUpdateAssemblies <document>
|
||||
~~~~~
|
||||
|
||||
Updates all assembly compounds in the XDE document.
|
||||
|
||||
**Example:**
|
||||
~~~~~
|
||||
XUpdateAssemblies D
|
||||
~~~~~
|
||||
|
||||
@subsection occt_draw_8_7_ XDE color commands
|
||||
|
||||
|
@ -156,14 +156,16 @@ You can then query or edit this Assembly node, the Main Item or another one (*my
|
||||
|
||||
**Note** that for the examples in the rest of this guide, *myAssembly* is always presumed to be accessed this way, so this information will not be repeated.
|
||||
|
||||
@subsubsection occt_xde_2_2_3 Updating the Assembly after Filling or Editing
|
||||
@subsubsection occt_xde_2_2_3 Updating the Assemblies after Filling or Editing
|
||||
Some actions in this chapter affect the content of the document, considered as an Assembly. As a result, you will sometimes need to update various representations (including the compounds).
|
||||
|
||||
To update the representations, use:
|
||||
~~~~~
|
||||
myAssembly->UpdateAssembly(aLabel);
|
||||
myAssembly->UpdateAssemblies();
|
||||
~~~~~
|
||||
Since this call is always used by the editing functions, you need not apply it for such functions. However, you will need this call if special edits, not using XCAF functions, are used on the document.
|
||||
This call performs a top-down update of the Assembly compounds stored in the document.
|
||||
|
||||
**Note** that you have to run this method manually to actualize your Assemblies after any low-level modifications on shapes.
|
||||
|
||||
@subsubsection occt_xde_2_2_4 Adding or Setting Top Level Shapes
|
||||
|
||||
|
@ -319,6 +319,9 @@ Standard_Boolean IGESCAFControl_Reader::Transfer (Handle(TDocStd_Document) &doc)
|
||||
|
||||
// end added by skl 13.10.2003
|
||||
|
||||
// Update assembly compounds
|
||||
STool->UpdateAssemblies();
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
@ -1774,6 +1774,7 @@ static Standard_Integer OCC23950 (Draw_Interpretor& di, Standard_Integer argc, c
|
||||
TDataStd_Name::Set(labelA0, "ASSEMBLY");
|
||||
|
||||
TDF_Label component01 = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main ())->AddComponent (labelA0, lab1, location0);
|
||||
XCAFDoc_DocumentTool::ShapeTool (aDoc->Main ())->UpdateAssemblies();
|
||||
|
||||
Quantity_Color yellow(1,1,0, Quantity_TOC_RGB);
|
||||
XCAFDoc_DocumentTool::ColorTool (labelA0)->SetColor (component01, yellow, XCAFDoc_ColorGen);
|
||||
|
@ -689,6 +689,9 @@ Standard_Boolean STEPCAFControl_Reader::Transfer (STEPControl_Reader &reader,
|
||||
// names) if requested
|
||||
ExpandSubShapes(STool, map, ShapePDMap);
|
||||
|
||||
// Update assembly compounds
|
||||
STool->UpdateAssemblies();
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <XCAFDoc.hxx>
|
||||
#include <XCAFDoc_GraphNode.hxx>
|
||||
#include <XCAFDoc_Location.hxx>
|
||||
@ -415,13 +416,6 @@ void XCAFDoc_ShapeTool::SetShape (const TDF_Label& L, const TopoDS_Shape& S)
|
||||
if(!myShapeLabels.IsBound(S)) {
|
||||
myShapeLabels.Bind(S,L);
|
||||
}
|
||||
|
||||
//:abv 31.10.01: update assemblies that refer a shape
|
||||
TDF_LabelSequence Labels;
|
||||
if ( GetUsers ( L, Labels, Standard_True ) ) {
|
||||
for ( Standard_Integer i=Labels.Length(); i >=1; i-- )
|
||||
UpdateAssembly ( Labels(i) );
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -954,8 +948,6 @@ TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
|
||||
L = aTag.NewChild(assembly);
|
||||
MakeReference ( L, compL, Loc );
|
||||
|
||||
// update assembly`s TopoDS_Shape
|
||||
UpdateAssembly ( assembly );
|
||||
return L;
|
||||
}
|
||||
|
||||
@ -986,34 +978,31 @@ TDF_Label XCAFDoc_ShapeTool::AddComponent (const TDF_Label& assembly,
|
||||
|
||||
void XCAFDoc_ShapeTool::RemoveComponent (const TDF_Label& comp) const
|
||||
{
|
||||
if ( IsComponent(comp) ) {
|
||||
if ( IsComponent(comp) )
|
||||
{
|
||||
comp.ForgetAllAttributes();
|
||||
UpdateAssembly(comp.Father());
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UpdateAssembly
|
||||
//function : UpdateAssemblies
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void XCAFDoc_ShapeTool::UpdateAssembly (const TDF_Label& L) const
|
||||
void XCAFDoc_ShapeTool::UpdateAssemblies()
|
||||
{
|
||||
if ( ! IsAssembly(L) ) return;
|
||||
// We start from the free shapes (roots in the assembly structure)
|
||||
TDF_LabelSequence aRootLabels;
|
||||
GetFreeShapes(aRootLabels);
|
||||
|
||||
TopoDS_Compound newassembly;
|
||||
BRep_Builder b;
|
||||
b.MakeCompound(newassembly);
|
||||
// Iterate over the free shapes
|
||||
for ( TDF_LabelSequence::Iterator anIt(aRootLabels); anIt.More(); anIt.Next() )
|
||||
{
|
||||
const TDF_Label& aRootLab = anIt.Value();
|
||||
|
||||
TDF_ChildIterator chldLabIt(L);
|
||||
for (; chldLabIt.More(); chldLabIt.Next() ) {
|
||||
TDF_Label subLabel = chldLabIt.Value();
|
||||
if ( IsComponent ( subLabel ) ) {
|
||||
b.Add(newassembly, GetShape(subLabel));
|
||||
}
|
||||
TopoDS_Shape anAssemblyShape;
|
||||
updateComponent(aRootLab, anAssemblyShape);
|
||||
}
|
||||
TNaming_Builder tnBuild(L);
|
||||
tnBuild.Generated(newassembly);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@ -1907,3 +1896,114 @@ void XCAFDoc_ShapeTool::makeSubShape (const TDF_Label& Part, const TopoDS_Shape&
|
||||
makeSubShape(Part, aChildShape);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : updateComponent
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean XCAFDoc_ShapeTool::updateComponent(const TDF_Label& theItemLabel,
|
||||
TopoDS_Shape& theUpdatedShape) const
|
||||
{
|
||||
if ( !IsAssembly(theItemLabel) )
|
||||
return Standard_False; // Do nothing for non-assemblies
|
||||
|
||||
// Get the currently stored compound for the assembly
|
||||
TopoDS_Shape aCurrentRootShape;
|
||||
GetShape(theItemLabel, aCurrentRootShape);
|
||||
|
||||
// Get components of the assembly
|
||||
TDF_LabelSequence aComponentLabs;
|
||||
GetComponents(theItemLabel, aComponentLabs);
|
||||
|
||||
// This flag indicates whether to update the compound of the assembly
|
||||
Standard_Boolean isModified = Standard_False;
|
||||
|
||||
// Compare the number of components in XDE structure with the number of
|
||||
// components in topological structure. A component may happen to be removed,
|
||||
// so we have to update the assembly compound
|
||||
Standard_Integer aNumTopoComponents = 0;
|
||||
for ( TopoDS_Iterator aTopIt(aCurrentRootShape); aTopIt.More(); aTopIt.Next() )
|
||||
aNumTopoComponents++;
|
||||
//
|
||||
if ( aNumTopoComponents != aComponentLabs.Length() )
|
||||
isModified = Standard_True;
|
||||
|
||||
// Iterate over the assembly components. If at least one component is
|
||||
// modified (this is the recursive check), then the actually stored
|
||||
// compound has to be updated
|
||||
TopTools_ListOfShape aComponentShapes;
|
||||
//
|
||||
for ( TDF_LabelSequence::Iterator aCompIt(aComponentLabs); aCompIt.More(); aCompIt.Next() )
|
||||
{
|
||||
const TDF_Label& aComponentLab = aCompIt.Value();
|
||||
|
||||
// Take the referred assembly item (ultimately, a part for an instance)
|
||||
TDF_Label aComponentRefLab;
|
||||
GetReferredShape(aComponentLab, aComponentRefLab);
|
||||
|
||||
// Shape comes with some placement transformation here
|
||||
TopoDS_Shape aComponentShape;
|
||||
GetShape(aComponentLab, aComponentShape);
|
||||
TopLoc_Location aComponentLoc = aComponentShape.Location();
|
||||
|
||||
// If the component is a sub-assembly, then its associated compound
|
||||
// has to be processed in the same manner
|
||||
if ( IsAssembly(aComponentRefLab) )
|
||||
{
|
||||
// Recursive call
|
||||
if ( updateComponent(aComponentRefLab, aComponentShape) )
|
||||
{
|
||||
if ( !isModified )
|
||||
isModified = Standard_True;
|
||||
|
||||
aComponentShape.Location(aComponentLoc); // Apply placement
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search for a part in the actual compound of the ultimate assembly.
|
||||
// If the part is there, then the compound is up-to-date, so it does
|
||||
// not require rebuilding
|
||||
Standard_Boolean isPartFound = Standard_False;
|
||||
for ( TopoDS_Iterator aTopoIt(aCurrentRootShape); aTopoIt.More(); aTopoIt.Next() )
|
||||
{
|
||||
if ( aTopoIt.Value() == aComponentShape )
|
||||
{
|
||||
isPartFound = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isPartFound && !isModified )
|
||||
isModified = Standard_True; // Part has been modified somewhere, so the compound
|
||||
// has to be rebuilt
|
||||
}
|
||||
|
||||
// Fill the list of shapes composing a new compound for the assembly
|
||||
aComponentShapes.Append(aComponentShape);
|
||||
}
|
||||
|
||||
// If any component is modified, we update the currently stored shape
|
||||
if ( isModified )
|
||||
{
|
||||
TopoDS_Compound anUpdatedCompound;
|
||||
BRep_Builder aBB;
|
||||
aBB.MakeCompound(anUpdatedCompound);
|
||||
|
||||
// Compose new compound
|
||||
for ( TopTools_ListIteratorOfListOfShape aShapeIt(aComponentShapes); aShapeIt.More(); aShapeIt.Next() )
|
||||
{
|
||||
aBB.Add( anUpdatedCompound, aShapeIt.Value() );
|
||||
}
|
||||
|
||||
// Store the updated shape as an output
|
||||
theUpdatedShape = anUpdatedCompound;
|
||||
|
||||
// Use topological naming services to store the updated shape in XDE
|
||||
TNaming_Builder NB(theItemLabel);
|
||||
NB.Generated(theUpdatedShape);
|
||||
}
|
||||
|
||||
return isModified;
|
||||
}
|
||||
|
@ -286,8 +286,8 @@ public:
|
||||
//! Removes a component from its assembly
|
||||
Standard_EXPORT void RemoveComponent (const TDF_Label& comp) const;
|
||||
|
||||
//! Update an assembly at label <L>
|
||||
Standard_EXPORT void UpdateAssembly (const TDF_Label& L) const;
|
||||
//! Top-down update for all assembly compounds stored in the document.
|
||||
Standard_EXPORT void UpdateAssemblies();
|
||||
|
||||
//! Finds a label for subshape <sub> of shape stored on
|
||||
//! label shapeL
|
||||
@ -421,7 +421,12 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
|
||||
//! Checks recursively if the given assembly item is modified. If so, its
|
||||
//! associated compound is updated. Returns true if the assembly item is
|
||||
//! modified, false -- otherwise.
|
||||
Standard_EXPORT Standard_Boolean updateComponent(const TDF_Label& theAssmLabel,
|
||||
TopoDS_Shape& theUpdatedShape) const;
|
||||
|
||||
//! Adds a new top-level (creates and returns a new label)
|
||||
//! For internal use. Used by public method AddShape.
|
||||
Standard_EXPORT TDF_Label addShape (const TopoDS_Shape& S, const Standard_Boolean makeAssembly = Standard_True);
|
||||
|
@ -815,6 +815,31 @@ static Standard_Integer setStyledComponent (Draw_Interpretor& di, Standard_Integ
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Standard_Integer updateAssemblies(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
di << "Use: " << argv[0] << " Doc\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get XDE document
|
||||
Handle(TDocStd_Document) aDoc;
|
||||
DDocStd::GetDocument(argv[1], aDoc);
|
||||
if ( aDoc.IsNull() )
|
||||
return 1;
|
||||
|
||||
// Get XDE shape tool
|
||||
Handle(XCAFDoc_ShapeTool)
|
||||
aShapeTool = XCAFDoc_DocumentTool::ShapeTool( aDoc->Main() );
|
||||
|
||||
// Update assemblies
|
||||
aShapeTool->UpdateAssemblies();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : InitCommands
|
||||
//purpose :
|
||||
@ -913,4 +938,6 @@ void XDEDRAW_Shapes::InitCommands(Draw_Interpretor& di)
|
||||
di.Add ("XSetInstanceSHUO","Doc shape \t: sets the SHUO structure for indicated component",
|
||||
__FILE__, setStyledComponent, g);
|
||||
|
||||
di.Add ("XUpdateAssemblies","Doc \t: updates assembly compounds",
|
||||
__FILE__, updateAssemblies, g);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ if { ( [regexp {Compiler: MS Visual C[+][+] ([0-9]+)} $dver res ver] && $ver < 1
|
||||
( [regexp {Compiler: GCC ([0-9]+[.][0-9]+)} $dver res ver] && $ver < 4.8 ) } {
|
||||
puts "TODO OCC28217 ALL: TEST INCOMPLETE"
|
||||
puts "TODO OCC28217 Windows: An exception was caught"
|
||||
puts "TODO OCC28217 Windows: \\*\\* Exception \\*\\*.*"
|
||||
puts "TODO OCC28217 Windows: \\*\\* Exception \\*\\*"
|
||||
puts "TODO ?OCC28217 Linux: An exception was caught"
|
||||
puts "TODO ?OCC28217 Linux: \\*\\* Exception \\*\\*.*"
|
||||
puts "TODO ?OCC28217 Linux: \\*\\*\\* Abort"
|
||||
|
29
tests/bugs/xde/bug28055_1
Normal file
29
tests/bugs/xde/bug28055_1
Normal file
@ -0,0 +1,29 @@
|
||||
puts "============"
|
||||
puts "CR28055"
|
||||
puts "============"
|
||||
puts ""
|
||||
|
||||
##########################################################################
|
||||
# Add UpdateAssemblies() method for top-down update of assembly compounds
|
||||
##########################################################################
|
||||
|
||||
ReadStep d [locate_data_file trj3_as1-tc-214.stp]
|
||||
XShow d
|
||||
vfit
|
||||
vsetdispmode 1
|
||||
|
||||
# First check verifies that originally there is 18 solid instances
|
||||
XGetOneShape model_before d
|
||||
checknbshapes model_before -solid 18 -t
|
||||
|
||||
checkview -screenshot -3d -path ${imagedir}/${::casename}_1.png
|
||||
|
||||
XRemoveComponent d 0:1:1:1:1
|
||||
XUpdateAssemblies d
|
||||
XShow d
|
||||
|
||||
checkview -screenshot -3d -path ${imagedir}/${::casename}_2.png
|
||||
|
||||
# Second check verifies that after component removal 7 instances go away
|
||||
XGetOneShape model_after d
|
||||
checknbshapes model_after -solid 11 -t
|
60
tests/bugs/xde/bug28055_2
Normal file
60
tests/bugs/xde/bug28055_2
Normal file
@ -0,0 +1,60 @@
|
||||
pload QAcommands
|
||||
|
||||
puts "============"
|
||||
puts "CR28055"
|
||||
puts "============"
|
||||
puts ""
|
||||
|
||||
##########################################################################
|
||||
# Add UpdateAssemblies() method for top-down update of assembly compounds
|
||||
##########################################################################
|
||||
|
||||
##########################################################################
|
||||
proc IsSame {s1 s2} {
|
||||
global $s1 $s2
|
||||
if {[IsSameShapes $s1 $s2] == 1} {return 1}
|
||||
return 0
|
||||
}
|
||||
##########################################################################
|
||||
|
||||
ReadStep d [locate_data_file trj3_as1-tc-214.stp]
|
||||
XShow d
|
||||
vfit
|
||||
vsetdispmode 1
|
||||
|
||||
# Explode on solids for comparison
|
||||
XGetOneShape model1 d
|
||||
explode model1 So
|
||||
|
||||
checkview -screenshot -3d -path ${imagedir}/${::casename}_1.png
|
||||
|
||||
# Update part's geometry
|
||||
box box_nut -2 -2 0 22 18 8;
|
||||
XSetShape d 0:1:1:5 box_nut
|
||||
XUpdateAssemblies d
|
||||
XShow d
|
||||
|
||||
# Explode on solids for comparison
|
||||
XGetOneShape model2 d
|
||||
explode model2 So
|
||||
|
||||
# 0 means "different", 1 means "same"
|
||||
set same_mask {1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 0}; list
|
||||
set n [llength $same_mask]
|
||||
|
||||
# Compare subshapes (exploded compounds) with respect to the reference mask
|
||||
set i 1
|
||||
foreach same_flag $same_mask {
|
||||
set same [IsSame model1_$i model2_$i]
|
||||
puts "Comparison result for subshape $i: $same"
|
||||
if {$same!=$same_flag} {
|
||||
if {$same_flag==1} {
|
||||
puts "Error: shapes are expected to be identical"
|
||||
} else {
|
||||
puts "Error: shapes are expected to be different"
|
||||
}
|
||||
}
|
||||
incr i
|
||||
}
|
||||
|
||||
checkview -screenshot -3d -path ${imagedir}/${::casename}_2.png
|
Loading…
x
Reference in New Issue
Block a user