1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

0027142: Data Exchange - add possibility to set location in XCAFDoc_ShapeTool interface

This commit is contained in:
aba
2016-02-08 14:47:57 +03:00
committed by smoskvin
parent aaacd83510
commit f8d4cfbb80
4 changed files with 278 additions and 0 deletions

View File

@@ -416,6 +416,40 @@ void XCAFDoc_ShapeTool::MakeReference (const TDF_Label &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
//purpose : private

View File

@@ -401,6 +401,15 @@ public:
//! from upper_usage component to next_usage
//! Returns null attribute if no SHUO found
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
Standard_EXPORT Standard_Boolean Expand (const TDF_Label& Shape);

View File

@@ -18,6 +18,8 @@
#include <DBRep.hxx>
#include <DDocStd.hxx>
#include <Draw.hxx>
#include <gp_Ax1.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <Message.hxx>
#include <NCollection_DataMap.hxx>
@@ -1113,6 +1115,127 @@ static Standard_Integer XAutoNaming (Draw_Interpretor& theDI,
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
//purpose :
@@ -1222,6 +1345,20 @@ 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 ("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",
__FILE__, updateAssemblies, g);