1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0029967: Draw Harness - command bounding has annoying syntax

Bnd_OBB constructor from Bnd_Box is fixed for VOID input.

DRAW command bounding command is adjusted:
- Support of old syntax 'bounding shape'is restored.
- Exception on VOID bounding box is avoided.
- Arguments are handled in case-insensitive way.
- Options -s, -perfmeter, and ability to set result as first argument are removed as redundant.
- Help is moved to command definition.

Separate command OCC29311 is added (in QADraw) to do the same as option -perfmeter did; tests are updated.
This commit is contained in:
kgv
2018-07-20 13:07:47 +03:00
committed by bugmaster
parent 3dc5809557
commit 1f26f80bb7
67 changed files with 335 additions and 331 deletions

View File

@@ -66,6 +66,12 @@ Standard_IMPORT Draw_Viewer dout;
static void ConvertBndToShape(const Bnd_OBB& theBox,
const char* const theName)
{
if (theBox.IsVoid())
{
DBRep::Set (theName, TopoDS_Shape());
return;
}
const gp_Pnt &aBaryCenter = theBox.Center();
const gp_XYZ &aXDir = theBox.XDirection(),
&aYDir = theBox.YDirection(),
@@ -455,6 +461,29 @@ static Standard_Integer getcoords(Draw_Interpretor& di,Standard_Integer n,const
return 0;
}
//! Parse 6 real values for defining AABB.
static Standard_Boolean parseMinMax (const char** theArgVec, Bnd_Box& theBox)
{
const TCollection_AsciiString aMin[3] = { theArgVec[0], theArgVec[1], theArgVec[2] };
const TCollection_AsciiString aMax[3] = { theArgVec[3], theArgVec[4], theArgVec[5] };
if (!aMin[0].IsRealValue()
|| !aMin[1].IsRealValue()
|| !aMin[2].IsRealValue()
|| !aMax[0].IsRealValue()
|| !aMax[1].IsRealValue()
|| !aMax[2].IsRealValue())
{
return Standard_False;
}
const gp_Pnt aPntMin (aMin[0].RealValue(), aMin[1].RealValue(), aMin[2].RealValue());
const gp_Pnt aPntMax (aMax[0].RealValue(), aMax[1].RealValue(), aMax[2].RealValue());
theBox.SetVoid();
theBox.Add (aPntMin);
theBox.Add (aPntMax);
return Standard_True;
}
//=======================================================================
//function : BoundBox
//purpose :
@@ -463,200 +492,132 @@ static Standard_Integer BoundBox(Draw_Interpretor& theDI,
Standard_Integer theNArg,
const char** theArgVal)
{
if(theNArg < 2)
{
theDI << "Use: " << theArgVal[0] << " {-s shape | -c xmin ymin zmin xmax ymax zmax} "
"[-obb]\n\t\t[-shape name] [-dump] [-notriangulation]\n\t\t"
"[-perfmeter name NbIters] [-nodraw] [-optimal] [-exttoler]\n\t\t"
"[-save xmin ymin zmin xmax ymax zmax]\n\n\n";
theDI << "Computes a bounding box (BndBox). Two types of the source data are supported:\n";
theDI << " * \"-s\"-option sets the shape, which will be circumscribed by the BndBox;\n";
theDI << " * \"-c\"-option sets two opposite corners (having (xmin, ymin, zmin) and\n\t"
"(xmax, ymax, zmax) coordinates) of the resulting\n\taxis-aligned BndBox (AABB).\n";
theDI << "\nThe following options are supported:\n";
theDI << " * \"-obb\". If it is switched on then the oriented BndBox (OBB) will "
"be\n\tcreated. Otherwise, AABB will be created.\n";
theDI << " * \"-shape\". If it is switched on then the resulting BndBox will be "
"stored\n\tas a shape (solid) with specified name.\n";
theDI << " * \"-nodraw\". If it is switched on then the resulting BndBox will not be\n\t"
"drawn as DRAW-object.\n";
theDI << " * \"-dump\". Prints the information about the created BndBox.\n";
theDI << " * \"-notriangulation\". By default, AABB is built from existing mesh.\n\t"
"This option allows ignoring triangulation.\n";
theDI << " * \"-save\". Stores the information about created AABB in "
"specified variables.\n";
theDI << " * \"-optimal\". If it is switched on then the AABB will be optimal.\n\t"
"This option is useful for OBB, too. It allows constructing\n\toptimal "
"initial AABB.\n";
theDI << " * \"-exttoler\". If it is switched on then the resulting box will be "
"extended\n\ton the tolerance of the source shape.\n";
theDI << " * \"-perfmeter\" - Auxiliary option. It provides compatibility "
"with\n\tOCCT-test system. \"name\" is the counter name for "
"\"chrono\"-TCL-command.\n\tNbIters is the number of iterations.\n";
return 1;
}
// 1. Parse arguments
TopoDS_Shape aShape;
Bnd_Box anAABB;
Standard_Boolean doPrint = Standard_False;
Standard_Boolean useOldSyntax = Standard_False;
Standard_Boolean isOBB = Standard_False;
Standard_Boolean hasToPrint = Standard_False,
isTriangulationReq = Standard_True,
isOptimal = Standard_False,
isTolerUsed = Standard_False,
hasToDraw = Standard_True;
Standard_Integer aNbIters = 1;
Standard_Integer aStartIdxToSave = -1,
aStartIdxToCreate = -1,
aNameToShape = -1,
anIdxCounterName = -1;
for(Standard_Integer anAIdx = 1; anAIdx < theNArg; anAIdx++)
Standard_Boolean isTriangulationReq = Standard_True;
Standard_Boolean isOptimal = Standard_False;
Standard_Boolean isTolerUsed = Standard_False;
Standard_Boolean hasToDraw = Standard_True;
TCollection_AsciiString anOutVars[6];
TCollection_AsciiString aResShapeName;
for (Standard_Integer anArgIter = 1; anArgIter < theNArg; ++anArgIter)
{
if(theArgVal[anAIdx][0] != '-')
{
theDI << "Error: Wrong option \"" << theArgVal[anAIdx] <<
"\". Please use \'-\' symbol\n";
return 1;
}
if(!strcmp(theArgVal[anAIdx], "-s"))
{
aShape = DBRep::Get(theArgVal[++anAIdx]);
if(aShape.IsNull())
{
theDI << "Error: Argument " << theArgVal[anAIdx] << " is not a shape.\n";
return 1;
}
}
else if(!strcmp(theArgVal[anAIdx], "-c"))
{
aStartIdxToCreate = anAIdx + 1;
anAIdx += 6;
}
else if(!strncmp(theArgVal[anAIdx], "-obb", 4))
TCollection_AsciiString anArgCase (theArgVal[anArgIter]);
anArgCase.LowerCase();
if (anArgCase == "-obb")
{
isOBB = Standard_True;
}
else if(!strncmp(theArgVal[anAIdx], "-shape", 4))
else if (anArgCase == "-aabb")
{
aNameToShape = ++anAIdx;
isOBB = Standard_False;
}
else if(!strncmp(theArgVal[anAIdx], "-dump", 4))
else if (anArgCase == "-shape"
&& anArgIter + 1 < theNArg
&& aResShapeName.IsEmpty())
{
hasToPrint = Standard_True;
aResShapeName = theArgVal[++anArgIter];
hasToDraw = Standard_False;
}
else if(!strncmp(theArgVal[anAIdx], "-save", 4))
else if (anArgCase == "-dump"
|| anArgCase == "-print")
{
aStartIdxToSave = anAIdx+1;
anAIdx += 6;
doPrint = Standard_True;
}
else if(!strncmp(theArgVal[anAIdx], "-notriangulation", 9))
else if (anArgCase == "-save"
&& anArgIter + 6 < theNArg
&& anOutVars[0].IsEmpty())
{
for (int aCompIter = 0; aCompIter < 6; ++aCompIter)
{
anOutVars[aCompIter] = theArgVal[anArgIter + aCompIter + 1];
}
anArgIter += 6;
}
else if (anArgCase == "-notriangulation")
{
isTriangulationReq = Standard_False;
}
else if(!strncmp(theArgVal[anAIdx], "-perfmeter", 8))
{
anIdxCounterName = ++anAIdx;
aNbIters = Draw::Atoi(theArgVal[++anAIdx]);
}
else if(!strncmp(theArgVal[anAIdx], "-optimal", 4))
else if (anArgCase == "-optimal")
{
isOptimal = Standard_True;
}
else if(!strcmp(theArgVal[anAIdx], "-exttoler"))
else if (anArgCase == "-exttoler")
{
isTolerUsed = Standard_True;
}
else if(!strcmp(theArgVal[anAIdx], "-nodraw"))
else if (anArgCase == "-nodraw")
{
hasToDraw = Standard_False;
}
else if (aShape.IsNull()
&& !DBRep::Get (theArgVal[anArgIter]).IsNull())
{
aShape = DBRep::Get (theArgVal[anArgIter]);
}
else if (anAABB.IsVoid()
&& anArgIter + 5 < theNArg
&& parseMinMax (theArgVal + anArgIter, anAABB))
{
anArgIter += 5;
}
else
{
theDI << "Error: Unknown option \"" << theArgVal[anAIdx] << "\".\n";
std::cout << "Syntax error at argument '" << theArgVal[anArgIter] << "'.\n";
return 1;
}
}
if(aShape.IsNull() && (aStartIdxToCreate < 0))
if (anAABB.IsVoid()
&& aShape.IsNull())
{
theDI << "Error: One of the options \'-s\' or \'-c\' must be set necessarily.\n";
std::cout << "Syntax error: input is not specified (neither shape nor coordinates)\n";
return 1;
}
else if (!anAABB.IsVoid()
&& (isOBB || isOptimal || isTolerUsed))
{
std::cout << "Syntax error: Options -obb, -optimal and -extToler cannot be used for explicitly defined AABB.\n";
return 1;
}
else if (isOBB
&& !anOutVars[0].IsEmpty())
{
std::cout << "Error: Option -save works only with axes-aligned boxes.\n";
return 1;
}
if(aStartIdxToCreate > 0)
// enable printing (old syntax) if neither saving to shape nor to DRAW variables is requested
if (! doPrint && anOutVars[0].IsEmpty() && aResShapeName.IsEmpty())
{
if(!aShape.IsNull())
{
theDI << "Error: Options \'-s\' and \'-c\' are fail for using simultaneously.\n";
return 1;
}
else if(isOBB)
{
theDI << "Error: Options \'-c\' and \"-obb\" are fail for using simultaneously.\n";
return 1;
}
}
if(isOptimal)
{
if(aShape.IsNull())
{
theDI << "Error: Options \"-optimal\" is used without any shape. "
"Use \'-s\'-option.\n";
return 1;
}
}
if(isTolerUsed)
{
if(aShape.IsNull())
{
theDI << "Error: Option \"-exttoler\" is used without any shape. "
"Use \'-s\'-option.\n";
return 1;
}
doPrint = Standard_True;
useOldSyntax = Standard_True;
}
// 2. Compute box and save results
Handle(Draw_Box) aDB;
OSD_Timer aTimer;
if(isOBB)
if (isOBB)
{
if(aStartIdxToSave > 0)
{
theDI << "Error: Option \"-save\" work only with axes-aligned boxes.\n";
return 1;
}
Bnd_OBB anOBB;
Standard_Integer aN = aNbIters;
BRepBndLib::AddOBB(aShape, anOBB, isTriangulationReq, isOptimal, isTolerUsed);
aTimer.Start();
while(aN-- > 0)
{
anOBB.SetVoid();
BRepBndLib::AddOBB(aShape, anOBB, isTriangulationReq, isOptimal, isTolerUsed);
}
aTimer.Stop();
if(anOBB.IsVoid())
if (anOBB.IsVoid())
{
theDI << "Void box.\n";
hasToPrint = Standard_False;
}
const gp_Pnt &aBaryCenter= anOBB.Center();
const gp_XYZ &aXDir = anOBB.XDirection(),
&aYDir = anOBB.YDirection(),
&aZDir = anOBB.ZDirection();
Standard_Real aHalfX = anOBB.XHSize(),
aHalfY = anOBB.YHSize(),
aHalfZ = anOBB.ZHSize();
if(hasToPrint)
else if (doPrint)
{
const gp_Pnt &aBaryCenter= anOBB.Center();
const gp_XYZ &aXDir = anOBB.XDirection(),
&aYDir = anOBB.YDirection(),
&aZDir = anOBB.ZDirection();
theDI << "Oriented bounding box\n";
theDI << "Center: " << aBaryCenter.X() << " " <<
aBaryCenter.Y() << " " <<
@@ -664,116 +625,92 @@ static Standard_Integer BoundBox(Draw_Interpretor& theDI,
theDI << "X-axis: " << aXDir.X() << " " << aXDir.Y() << " " << aXDir.Z() << "\n";
theDI << "Y-axis: " << aYDir.X() << " " << aYDir.Y() << " " << aYDir.Z() << "\n";
theDI << "Z-axis: " << aZDir.X() << " " << aZDir.Y() << " " << aZDir.Z() << "\n";
theDI << "Half X: " << aHalfX << "\n" <<
"Half Y: " << aHalfY << "\n" << "Half Z: " << aHalfZ << "\n";
theDI << "Half X: " << anOBB.XHSize() << "\n"
<< "Half Y: " << anOBB.YHSize() << "\n"
<< "Half Z: " << anOBB.ZHSize() << "\n";
}
if(hasToDraw)
aDB = new Draw_Box(anOBB, Draw_orange);
if(aNameToShape > 0)
if (hasToDraw
&& !anOBB.IsVoid())
{
ConvertBndToShape(anOBB, theArgVal[aNameToShape]);
aDB = new Draw_Box (anOBB, Draw_orange);
}
if (!aResShapeName.IsEmpty())
{
ConvertBndToShape (anOBB, aResShapeName.ToCString());
}
}
else // if(!isOBB)
{
Standard_Real aXmin = RealFirst(), aYmin = RealFirst(), aZmin = RealFirst(),
aXMax = RealLast(), aYMax = RealLast(), aZMax = RealLast();
Bnd_Box anAABB;
if(aStartIdxToCreate < 0)
if (!aShape.IsNull())
{
Standard_Integer aN = aNbIters;
anAABB.SetVoid ();
if(isOptimal)
{
aTimer.Start();
while(aN-- > 0)
{
anAABB.SetVoid();
BRepBndLib::AddOptimal(aShape, anAABB, isTriangulationReq, isTolerUsed);
}
aTimer.Stop();
BRepBndLib::AddOptimal (aShape, anAABB, isTriangulationReq, isTolerUsed);
}
else
{
aTimer.Start();
while(aN-- > 0)
{
anAABB.SetVoid();
BRepBndLib::Add(aShape, anAABB, isTriangulationReq);
}
aTimer.Stop();
BRepBndLib::Add (aShape, anAABB, isTriangulationReq);
}
}
if (anAABB.IsVoid())
{
theDI << "Void box.\n";
}
else
{
if(anIdxCounterName > 0)
const gp_Pnt aMin = anAABB.CornerMin();
const gp_Pnt aMax = anAABB.CornerMax();
// print to DRAW
if (doPrint)
{
theDI << "Error: Option \"-perfmeter\"does not work if the option \'-c\' "
"is switched on.\n";
return 1;
if (useOldSyntax)
{
theDI << aMin.X () << " " << aMin.Y () << " " << aMin.Z () << " "
<< aMax.X () << " " << aMax.Y () << " " << aMax.Z () << "\n";
}
else
{
theDI << "Axes-aligned bounding box\n";
theDI << "X-range: " << aMin.X () << " " << aMax.X () << "\n" <<
"Y-range: " << aMin.Y() << " " << aMax.Y() << "\n" <<
"Z-range: " << aMin.Z () << " " << aMax.Z () << "\n";
}
}
Standard_Integer anIdx = aStartIdxToCreate;
aXmin = Draw::Atof(theArgVal[anIdx++]);
aYmin = Draw::Atof(theArgVal[anIdx++]);
aZmin = Draw::Atof(theArgVal[anIdx++]);
aXMax = Draw::Atof(theArgVal[anIdx++]);
aYMax = Draw::Atof(theArgVal[anIdx++]);
aZMax = Draw::Atof(theArgVal[anIdx++]);
anAABB.Add(gp_Pnt(aXmin, aYmin, aZmin));
anAABB.Add(gp_Pnt(aXMax, aYMax, aZMax));
}
if(anAABB.IsVoid())
{
theDI << "Void box.\n";
hasToPrint = Standard_False;
}
if(hasToPrint || (aStartIdxToSave>0))
{
anAABB.Get(aXmin, aYmin, aZmin, aXMax, aYMax, aZMax);
if(hasToPrint)
// save DRAW variables
if (!anOutVars[0].IsEmpty())
{
theDI << "Axes-aligned bounding box\n";
theDI << "X-range: " << aXmin << " " << aXMax << "\n" <<
"Y-range: " << aYmin << " " << aYMax << "\n" <<
"Z-range: " << aZmin << " " << aZMax << "\n";
Draw::Set (anOutVars[0].ToCString(), aMin.X());
Draw::Set (anOutVars[1].ToCString(), aMin.Y());
Draw::Set (anOutVars[2].ToCString(), aMin.Z());
Draw::Set (anOutVars[3].ToCString(), aMax.X());
Draw::Set (anOutVars[4].ToCString(), aMax.Y());
Draw::Set (anOutVars[5].ToCString(), aMax.Z());
}
if(aStartIdxToSave > 0)
// add presentation to DRAW viewer
if (hasToDraw)
{
Draw::Set(theArgVal[aStartIdxToSave++], aXmin);
Draw::Set(theArgVal[aStartIdxToSave++], aYmin);
Draw::Set(theArgVal[aStartIdxToSave++], aZmin);
Draw::Set(theArgVal[aStartIdxToSave++], aXMax);
Draw::Set(theArgVal[aStartIdxToSave++], aYMax);
Draw::Set(theArgVal[aStartIdxToSave++], aZMax);
aDB = new Draw_Box (anAABB, Draw_orange);
}
}
if(hasToDraw)
aDB = new Draw_Box(anAABB, Draw_orange);
if(aNameToShape > 0)
// save as shape
if (!aResShapeName.IsEmpty())
{
ConvertBndToShape(anAABB, theArgVal[aNameToShape]);
ConvertBndToShape (anAABB, aResShapeName.ToCString());
}
}
if(hasToDraw)
dout << aDB;
if(anIdxCounterName > 0)
if (!aDB.IsNull())
{
theDI << "COUNTER " << theArgVal[anIdxCounterName] << ": " << aTimer.ElapsedTime() << "\n";
dout << aDB;
}
return 0;
}
@@ -1514,7 +1451,30 @@ void BRepTest::BasicCommands(Draw_Interpretor& theCommands)
__FILE__,
getcoords,g);
theCommands.Add("bounding", "enter the comand w/o any arguments to obtain the help.",
theCommands.Add ("bounding",
"bounding {shape | xmin ymin zmin xmax ymax zmax}"
"\n\t\t: [-obb] [-noTriangulation] [-optimal] [-extToler]"
"\n\t\t: [-dump] [-shape name] [-nodraw]"
"\n\t\t: [-save xmin ymin zmin xmax ymax zmax]"
"\n\t\t:"
"\n\t\t: Computes a bounding box. Two types of the source data are supported:"
"\n\t\t: a shape or AABB corners (xmin, ymin, zmin, xmax, ymax, zmax)."
"\n\t\t:"
"\n\t\t: Calculation options (applicable only if input is a shape):"
"\n\t\t: -obb Compute Oriented Bounding Box (OBB) instead of AABB."
"\n\t\t: -noTriangulation Force use of exact geometry for calculation"
"\n\t\t: even if triangulation is present."
"\n\t\t: -optimal Force calculation of optimal (more tight) AABB."
"\n\t\t: In case of OBB, applies to initial AABB used in OBB calculation."
"\n\t\t: -extToler Include tolerance of the shape in the resulting box."
"\n\t\t:"
"\n\t\t: Output options:"
"\n\t\t: -dump Prints the information about computed Bounding Box."
"\n\t\t: It is enabled by default (with plain old syntax for AABB)"
"\n\t\t: if neither -shape nor -save is specified."
"\n\t\t: -shape Stores computed box as solid in DRAW variable with specified name."
"\n\t\t: -save Stores min and max coordinates of AABB in specified variables."
"\n\t\t: -noDraw Avoid drawing resulting Bounding Box in DRAW viewer.",
__FILE__, BoundBox, g);
//