mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-21 10:13:43 +03:00
0027142: Data Exchange - add possibility to set location in XCAFDoc_ShapeTool interface
This commit is contained in:
parent
aaacd83510
commit
f8d4cfbb80
@ -416,6 +416,40 @@ void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &L,
|
|||||||
SetLabelNameByLink(L);
|
SetLabelNameByLink(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// function : SetLocation
|
||||||
|
// purpose :
|
||||||
|
//=======================================================================
|
||||||
|
Standard_Boolean XCAFDoc_ShapeTool::SetLocation (const TDF_Label& theShapeLabel,
|
||||||
|
const TopLoc_Location& theLoc,
|
||||||
|
TDF_Label& theRefLabel)
|
||||||
|
{
|
||||||
|
if (theLoc.IsIdentity())
|
||||||
|
{
|
||||||
|
theRefLabel = theShapeLabel;
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
// if input label is reference -> just change the location attribute
|
||||||
|
if (IsReference (theShapeLabel))
|
||||||
|
{
|
||||||
|
TopLoc_Location anOldLoc;
|
||||||
|
anOldLoc = GetLocation (theShapeLabel);
|
||||||
|
TopLoc_Location aNewLoc (theLoc.Transformation() * anOldLoc.Transformation());
|
||||||
|
XCAFDoc_Location::Set(theShapeLabel, aNewLoc);
|
||||||
|
theRefLabel = theShapeLabel;
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
// if input label is shape, and it is free -> create reference to the shape
|
||||||
|
if (IsShape(theShapeLabel) && IsFree(theShapeLabel))
|
||||||
|
{
|
||||||
|
theRefLabel = TDF_TagSource::NewChild (Label());
|
||||||
|
MakeReference (theRefLabel, theShapeLabel, theLoc);
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
// other cases of label meaning doesn't need to apply new location
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : addShape
|
//function : addShape
|
||||||
//purpose : private
|
//purpose : private
|
||||||
|
@ -402,6 +402,15 @@ public:
|
|||||||
//! Returns null attribute if no SHUO found
|
//! Returns null attribute if no SHUO found
|
||||||
Standard_EXPORT static Standard_Boolean FindSHUO (const TDF_LabelSequence& Labels, Handle(XCAFDoc_GraphNode)& theSHUOAttr);
|
Standard_EXPORT static Standard_Boolean FindSHUO (const TDF_LabelSequence& Labels, Handle(XCAFDoc_GraphNode)& theSHUOAttr);
|
||||||
|
|
||||||
|
//! Sets location to the shape label
|
||||||
|
//! If label is reference -> changes location attribute
|
||||||
|
//! If label is free shape -> creates reference with location to it
|
||||||
|
//! @param[in] theShapeLabel the shape label to change location
|
||||||
|
//! @param[in] theLoc location to set
|
||||||
|
//! @param[out] theRefLabel the reference label with new location
|
||||||
|
//! @return TRUE if new location was set
|
||||||
|
Standard_EXPORT Standard_Boolean SetLocation (const TDF_Label& theShapeLabel, const TopLoc_Location& theLoc, TDF_Label& theRefLabel);
|
||||||
|
|
||||||
//! Convert Shape (compound/compsolid/shell/wire) to assembly
|
//! Convert Shape (compound/compsolid/shell/wire) to assembly
|
||||||
Standard_EXPORT Standard_Boolean Expand (const TDF_Label& Shape);
|
Standard_EXPORT Standard_Boolean Expand (const TDF_Label& Shape);
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include <DBRep.hxx>
|
#include <DBRep.hxx>
|
||||||
#include <DDocStd.hxx>
|
#include <DDocStd.hxx>
|
||||||
#include <Draw.hxx>
|
#include <Draw.hxx>
|
||||||
|
#include <gp_Ax1.hxx>
|
||||||
|
#include <gp_Pnt.hxx>
|
||||||
#include <gp_Trsf.hxx>
|
#include <gp_Trsf.hxx>
|
||||||
#include <Message.hxx>
|
#include <Message.hxx>
|
||||||
#include <NCollection_DataMap.hxx>
|
#include <NCollection_DataMap.hxx>
|
||||||
@ -1113,6 +1115,127 @@ static Standard_Integer XAutoNaming (Draw_Interpretor& theDI,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// function : parseXYZ
|
||||||
|
// purpose : Converts three string arguments, to gp_XYZ with check
|
||||||
|
//=======================================================================
|
||||||
|
static Standard_Boolean parseXYZ (const char** theArgVec, gp_XYZ& thePnt)
|
||||||
|
{
|
||||||
|
const TCollection_AsciiString aXYZ[3] = {theArgVec[0], theArgVec[1], theArgVec[2] };
|
||||||
|
if (!aXYZ[0].IsRealValue (Standard_True)
|
||||||
|
|| !aXYZ[1].IsRealValue (Standard_True)
|
||||||
|
|| !aXYZ[2].IsRealValue (Standard_True))
|
||||||
|
{
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
thePnt.SetCoord (aXYZ[0].RealValue(), aXYZ[1].RealValue(), aXYZ[2].RealValue());
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
// function : setLocation
|
||||||
|
// purpose : Sets location to the shape at the label in XDE document
|
||||||
|
//=======================================================================
|
||||||
|
static Standard_Integer setLocation (Draw_Interpretor& , Standard_Integer theArgNb, const char** theArgVec)
|
||||||
|
{
|
||||||
|
if (theArgNb < 4)
|
||||||
|
{
|
||||||
|
Message::SendFail() << "Error: not enough arguments, see help " << theArgVec[0] << " for details";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// get and check the document
|
||||||
|
Handle(TDocStd_Document) aDoc;
|
||||||
|
DDocStd::GetDocument (theArgVec[1], aDoc);
|
||||||
|
if (aDoc.IsNull ())
|
||||||
|
{
|
||||||
|
Message::SendFail() << "Error: " << theArgVec[1] << " is not a document";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// get and check the label
|
||||||
|
TDF_Label aShapeLabel;
|
||||||
|
TDF_Tool::Label (aDoc->GetData(), theArgVec[2], aShapeLabel);
|
||||||
|
if (aShapeLabel.IsNull ())
|
||||||
|
{
|
||||||
|
Message::SendFail() << "Error: no such Label: " << theArgVec[2];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// get the transformation
|
||||||
|
gp_Trsf aTransformation;
|
||||||
|
for (Standard_Integer anArgIter = 3; anArgIter < theArgNb; ++anArgIter)
|
||||||
|
{
|
||||||
|
gp_Trsf aCurTransformation;
|
||||||
|
gp_XYZ aMoveXYZ, aRotPnt, aRotAxis, aScalePnt;
|
||||||
|
Standard_Real aRotAngle, aScale;
|
||||||
|
TCollection_AsciiString anArg = theArgVec[anArgIter];
|
||||||
|
anArg.LowerCase();
|
||||||
|
|
||||||
|
if (anArg == "-rotate" &&
|
||||||
|
anArgIter + 7 < theArgNb &&
|
||||||
|
parseXYZ (theArgVec + anArgIter + 1, aRotPnt) &&
|
||||||
|
parseXYZ (theArgVec + anArgIter + 4, aRotAxis) &&
|
||||||
|
Draw::ParseReal (theArgVec[anArgIter + 7], aRotAngle))
|
||||||
|
{
|
||||||
|
anArgIter += 7;
|
||||||
|
aCurTransformation.SetRotation (gp_Ax1 (gp_Pnt (aRotPnt), gp_Dir (aRotAxis)), aRotAngle * (M_PI / 180.0));
|
||||||
|
}
|
||||||
|
else if (anArg == "-move" &&
|
||||||
|
anArgIter + 3 < theArgNb &&
|
||||||
|
parseXYZ (theArgVec + anArgIter + 1, aMoveXYZ))
|
||||||
|
{
|
||||||
|
anArgIter += 3;
|
||||||
|
aCurTransformation.SetTranslation (aMoveXYZ);
|
||||||
|
}
|
||||||
|
// first check scale with base point
|
||||||
|
else if (anArg == "-scale" &&
|
||||||
|
anArgIter + 4 < theArgNb &&
|
||||||
|
parseXYZ (theArgVec + anArgIter + 1, aScalePnt) &&
|
||||||
|
Draw::ParseReal (theArgVec[anArgIter + 4], aScale))
|
||||||
|
{
|
||||||
|
anArgIter += 4;
|
||||||
|
aCurTransformation.SetScale (gp_Pnt (aScalePnt), aScale);
|
||||||
|
}
|
||||||
|
// second check for scale with scale factor only
|
||||||
|
else if (anArg == "-scale" &&
|
||||||
|
anArgIter + 1 < theArgNb &&
|
||||||
|
Draw::ParseReal (theArgVec[anArgIter + 1], aScale))
|
||||||
|
{
|
||||||
|
anArgIter += 1;
|
||||||
|
aCurTransformation.SetScaleFactor (aScale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message::SendFail() << "Syntax error: unknown options '" << anArg << "', or incorrect option parameters";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
aTransformation.PreMultiply (aCurTransformation);
|
||||||
|
}
|
||||||
|
TopLoc_Location aLoc(aTransformation);
|
||||||
|
|
||||||
|
// Create the ShapeTool and try to set location
|
||||||
|
Handle(XCAFDoc_ShapeTool) anAssembly = XCAFDoc_DocumentTool::ShapeTool (aDoc->Main());
|
||||||
|
TDF_Label aRefLabel;
|
||||||
|
if (anAssembly->SetLocation (aShapeLabel, aLoc, aRefLabel))
|
||||||
|
{
|
||||||
|
if (aShapeLabel == aRefLabel)
|
||||||
|
{
|
||||||
|
Message::SendInfo() << "New location was set";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TCollection_AsciiString aLabelStr;
|
||||||
|
TDF_Tool::Entry(aRefLabel, aLabelStr);
|
||||||
|
Message::SendInfo() << "Reference to the shape at label " << aLabelStr << " was created and location was set";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Message::SendFail() << "Error: an attempt to set the location to a shape to which there is a reference, or to not a shape at all";
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : InitCommands
|
//function : InitCommands
|
||||||
//purpose :
|
//purpose :
|
||||||
@ -1223,6 +1346,20 @@ void XDEDRAW_Shapes::InitCommands(Draw_Interpretor& di)
|
|||||||
di.Add ("XSetInstanceSHUO","Doc shape \t: sets the SHUO structure for indicated component",
|
di.Add ("XSetInstanceSHUO","Doc shape \t: sets the SHUO structure for indicated component",
|
||||||
__FILE__, setStyledComponent, g);
|
__FILE__, setStyledComponent, g);
|
||||||
|
|
||||||
|
di.Add ("XSetLocation", R"(
|
||||||
|
Doc Label transformation [transformation ... ]
|
||||||
|
Applies given complex transformation to the shape at Label from Document.
|
||||||
|
The label may contain a reference to a shape, an assembly or simple shape.
|
||||||
|
The assembly or simple shape should not be referred by any reference.
|
||||||
|
Transformations:
|
||||||
|
'-move x y z' - move shape
|
||||||
|
'-rotate x y z dx dy dz angle' - rotate shape
|
||||||
|
'-scale [x y z] factor' - scale shape
|
||||||
|
Transformations are applied from left to right.
|
||||||
|
There can be more than one transformation of the same type.
|
||||||
|
At least one transformation must be specified.
|
||||||
|
)", __FILE__, setLocation, g);
|
||||||
|
|
||||||
di.Add ("XUpdateAssemblies","Doc \t: updates assembly compounds",
|
di.Add ("XUpdateAssemblies","Doc \t: updates assembly compounds",
|
||||||
__FILE__, updateAssemblies, g);
|
__FILE__, updateAssemblies, g);
|
||||||
|
|
||||||
|
98
tests/bugs/xde/bug27142
Normal file
98
tests/bugs/xde/bug27142
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
puts "=========="
|
||||||
|
puts "0027142: Data Exchange - add possibility to set location in XCAFDoc_ShapeTool interface"
|
||||||
|
puts "=========="
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
puts "TODO 0027142 ALL: Error: area of d1"
|
||||||
|
puts "TODO 0027142 ALL: Error: area of d2"
|
||||||
|
puts "TODO 0027142 ALL: Error: center of gravity"
|
||||||
|
|
||||||
|
pload OCAF XDE
|
||||||
|
Close Doc -silent
|
||||||
|
XNewDoc Doc
|
||||||
|
|
||||||
|
# Create five boxes 'a', 'b', 'c', 'd', 'e'
|
||||||
|
# Box 'e' will stay at origin of coords
|
||||||
|
# Boxes 'a', 'b', 'c', 'd' should form the new box of the size 2x2x1 at the point (3 3 0)
|
||||||
|
box a 1 1 1
|
||||||
|
box b 1 1 1
|
||||||
|
ttranslate b 1 1 0
|
||||||
|
compound a b ab
|
||||||
|
XAddShape Doc ab
|
||||||
|
SetName Doc 0:1:1:1 ab
|
||||||
|
SetName Doc 0:1:1:1:1 ref_a
|
||||||
|
SetName Doc 0:1:1:1:2 ref_b
|
||||||
|
SetName Doc 0:1:1:2 a
|
||||||
|
SetName Doc 0:1:1:3 b
|
||||||
|
box c 1 1 1
|
||||||
|
ttranslate c 1 0 0
|
||||||
|
box d 0.5 0.5 0.5
|
||||||
|
XAddShape Doc c
|
||||||
|
SetName Doc 0:1:1:4 ref_c
|
||||||
|
SetName Doc 0:1:1:5 c
|
||||||
|
XAddShape Doc d
|
||||||
|
SetName Doc 0:1:1:6 d
|
||||||
|
box e 1 1 1
|
||||||
|
XAddShape Doc e
|
||||||
|
SetName Doc 0:1:1:7 e
|
||||||
|
|
||||||
|
# Set location to the assembly (compound of boxes 'a' and 'b')
|
||||||
|
XSetLocation Doc 0:1:1:1 -rotate 0 0 0 0 0 1 90 -move 4 2 0
|
||||||
|
SetName Doc 0:1:1:8 ref_ab
|
||||||
|
# Set location to the reference to shape (box 'c')
|
||||||
|
XSetLocation Doc 0:1:1:4 -move 1 0 0 -move 1 3 0
|
||||||
|
# Set location to the simple shape (box 'd')
|
||||||
|
XSetLocation Doc 0:1:1:6 -move 2 2 0 -scale 2 2 0 2
|
||||||
|
SetName Doc 0:1:1:9 ref_d
|
||||||
|
|
||||||
|
# Write the document to files of different formats
|
||||||
|
WriteStep Doc ${imagedir}/step.step
|
||||||
|
WriteIges Doc ${imagedir}/iges.iges
|
||||||
|
XSave Doc ${imagedir}/xbf.xbf
|
||||||
|
Close Doc
|
||||||
|
|
||||||
|
# Read document back and make screenshots
|
||||||
|
vinit
|
||||||
|
ReadStep Doc1 ${imagedir}/step.step
|
||||||
|
XDisplay Doc1; vfit
|
||||||
|
vdump ${imagedir}/step.png
|
||||||
|
vclear
|
||||||
|
ReadIges Doc2 ${imagedir}/iges.iges
|
||||||
|
XDisplay Doc2; vfit
|
||||||
|
vdump ${imagedir}/iges.png
|
||||||
|
vclear
|
||||||
|
XOpen ${imagedir}/xbf.xbf Doc3
|
||||||
|
XDisplay Doc3; vfit
|
||||||
|
vdump ${imagedir}/xbf.png
|
||||||
|
vclose
|
||||||
|
|
||||||
|
# Get the box 'd' from the documents
|
||||||
|
XGetShape d1 Doc1 0:1:1:8
|
||||||
|
XGetShape d2 Doc2 0:1:1:4
|
||||||
|
XGetShape d3 Doc3 0:1:1:9
|
||||||
|
|
||||||
|
# Saving disk space
|
||||||
|
Close Doc1
|
||||||
|
Close Doc2
|
||||||
|
Close Doc3
|
||||||
|
file delete $imagedir/step.step
|
||||||
|
file delete $imagedir/iges.iges
|
||||||
|
file delete $imagedir/xbf.xbf
|
||||||
|
|
||||||
|
# Scale transformation doesn't apply in STEP format and incorrectly applies in IGES format
|
||||||
|
|
||||||
|
# Check the areas of the "problem" box 'd'
|
||||||
|
puts "Check area of the box from STEP file"
|
||||||
|
checkarea d1 6 1e-7 0.001
|
||||||
|
puts "Check area of the box from IGES file"
|
||||||
|
checkarea d2 6 1e-7 0.001
|
||||||
|
puts "Check area of the box from XBF file"
|
||||||
|
checkarea d3 6 1e-7 0.001
|
||||||
|
|
||||||
|
# Check the gravity centers of the "problem" box 'd'
|
||||||
|
puts "Check gravity center of the box from STEP file"
|
||||||
|
checkgravitycenter d1 -s 2.5 2.5 0.5 1e-7
|
||||||
|
puts "Check gravity center of the box from IGES file"
|
||||||
|
checkgravitycenter d2 -s 2.5 2.5 0.5 1e-7
|
||||||
|
puts "Check gravity center of the box from XBF file"
|
||||||
|
checkgravitycenter d3 -s 2.5 2.5 0.5 1e-7
|
Loading…
x
Reference in New Issue
Block a user