Loading files
// Created on: 1998-11-12
// Created by: Robert COUBLANC
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 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 <ViewerTest.hxx>
#include <AIS_PlaneTrihedron.hxx>
#include <Quantity_NameOfColor.hxx>
#include <Draw_Interpretor.hxx>
#include <Draw.hxx>
#include <Draw_Appli.hxx>
#include <DBRep.hxx>
#include <DBRep_DrawableShape.hxx>
#include <StdPrs_BRepFont.hxx>
#include <Font_FontMgr.hxx>
#include <Font_TextFormatter.hxx>
#include <Message.hxx>
#include <NCollection_LinearVector.hxx>
#include <NCollection_List.hxx>
#include <OSD_Chronometer.hxx>
#include <TCollection_AsciiString.hxx>
#include <V3d_Viewer.hxx>
#include <V3d_View.hxx>
#include <V3d.hxx>
#include <AIS_Shape.hxx>
#include <AIS_DisplayMode.hxx>
#include <AIS_PointCloud.hxx>
#include <BRepLib_PointCloudShape.hxx>
#include <Standard_Integer.hxx>
#include <NCollection_Map.hxx>
#include <ViewerTest_AutoUpdater.hxx>
#include <Standard_Transient.hxx>
#include <NCollection_DoubleMap.hxx>
#include <ViewerTest_EventManager.hxx>
#include <TopoDS_Solid.hxx>
#include <BRepTools.hxx>
#include <optional>
#include <BRep_Builder.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS.hxx>
#include <BRep_Tool.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <TopAbs.hxx>
#include <TopExp.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Face.hxx>
#include <Draw_Window.hxx>
#include <AIS_InteractiveObject.hxx>
#include <AIS_ColoredShape.hxx>
#include <AIS_InteractiveContext.hxx>
#include <Geom_Plane.hxx>
#include <gp_Pln.hxx>
#include <TCollection_ExtendedString.hxx>
#include <TCollection_HAsciiString.hxx>
#include <GC_MakePlane.hxx>
#include <gp_Circ.hxx>
#include <AIS_Axis.hxx>
#include <Geom_Axis2Placement.hxx>
#include <Geom_Axis1Placement.hxx>
#include <AIS_Trihedron.hxx>
#include <gp_Trsf.hxx>
#include <gp_Quaternion.hxx>
#include <TopLoc_Location.hxx>
#include <HLRAlgo_Projector.hxx>
#include <HLRBRep_Algo.hxx>
#include <HLRBRep_PolyAlgo.hxx>
#include <HLRBRep_PolyHLRToShape.hxx>
#include <HLRBRep_HLRToShape.hxx>
#include <Aspect_Window.hxx>
#include <Graphic3d_ArrayOfPoints.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Graphic3d_ArrayOfPolylines.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
#include <Graphic3d_ArrayOfTriangleFans.hxx>
#include <Graphic3d_ArrayOfTriangleStrips.hxx>
#include <Graphic3d_ArrayOfQuadrangles.hxx>
#include <Graphic3d_ArrayOfQuadrangleStrips.hxx>
#include <Graphic3d_ArrayOfPolygons.hxx>
#include <Graphic3d_AttribBuffer.hxx>
#include <Graphic3d_AspectMarker3d.hxx>
#include <Graphic3d_Group.hxx>
#include <Standard_Real.hxx>
#include <AIS_Circle.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <Geom_Circle.hxx>
#include <GC_MakeCircle.hxx>
#include <Select3D_SensitiveCircle.hxx>
#include <SelectMgr_EntityOwner.hxx>
#include <SelectMgr_Selection.hxx>
#include <StdFail_NotDone.hxx>
#include <StdPrs_ShadedShape.hxx>
#include <TopoDS_Wire.hxx>
#include <AIS_MultipleConnectedInteractive.hxx>
#include <AIS_ConnectedInteractive.hxx>
#include <AIS_TextLabel.hxx>
#include <Select3D_SensitiveSegment.hxx>
#include <Select3D_SensitivePrimitiveArray.hxx>
#include <Select3D_SensitivePoint.hxx>
#include <Select3D_SensitivePoly.hxx>
#include <StdPrs_Curve.hxx>
#include <BRepExtrema_ExtPC.hxx>
#include <BRepExtrema_ExtPF.hxx>
#include <Prs3d_Arrow.hxx>
#include <Prs3d_ArrowAspect.hxx>
#include <Prs3d_DatumAttribute.hxx>
#include <Prs3d_DatumAspect.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_VertexDrawMode.hxx>
#include <Prs3d_LineAspect.hxx>
#include <Prs3d_PointAspect.hxx>
#include <Prs3d_Presentation.hxx>
#include <Prs3d_TextAspect.hxx>
#include <Prs3d_ToolCylinder.hxx>
#include <Prs3d_ToolSphere.hxx>
#include <Prs3d_ToolTorus.hxx>
#include <Image_AlienPixMap.hxx>
#include <NCollection_Array1.hxx>
#include <NCollection_HArray1.hxx>
#include <NCollection_Sequence.hxx>
#include <NCollection_HSequence.hxx>
extern NCollection_DoubleMap<occ::handle<AIS_InteractiveObject>, TCollection_AsciiString>&
GetMapOfAIS();
extern bool VDisplayAISObject(const TCollection_AsciiString& theName,
const occ::handle<AIS_InteractiveObject>& theAISObj,
bool theReplaceIfExists = true);
extern occ::handle<AIS_InteractiveContext>& TheAISContext();
namespace
{
static bool convertToColor(
const occ::handle<NCollection_HSequence<TCollection_AsciiString>>& theColorValues,
Quantity_Color& theColor)
{
const char* anArgs[3] = {
theColorValues->Length() >= 1 ? theColorValues->Value(1).ToCString() : "",
theColorValues->Length() >= 2 ? theColorValues->Value(2).ToCString() : "",
theColorValues->Length() >= 3 ? theColorValues->Value(3).ToCString() : ""};
return Draw::ParseColor(theColorValues->Length(), anArgs, theColor) != 0;
}
static bool convertToDatumPart(const TCollection_AsciiString& theValue,
Prs3d_DatumParts& theDatumPart)
{
TCollection_AsciiString aValue = theValue;
aValue.LowerCase();
if (aValue == "origin")
{
theDatumPart = Prs3d_DatumParts_Origin;
}
else if (aValue == "xaxis")
{
theDatumPart = Prs3d_DatumParts_XAxis;
}
else if (aValue == "yaxis")
{
theDatumPart = Prs3d_DatumParts_YAxis;
}
else if (aValue == "zaxis")
{
theDatumPart = Prs3d_DatumParts_ZAxis;
}
else if (aValue == "xarrow")
{
theDatumPart = Prs3d_DatumParts_XArrow;
}
else if (aValue == "yarrow")
{
theDatumPart = Prs3d_DatumParts_YArrow;
}
else if (aValue == "zarrow")
{
theDatumPart = Prs3d_DatumParts_ZArrow;
}
else if (aValue == "xoyaxis")
{
theDatumPart = Prs3d_DatumParts_XOYAxis;
}
else if (aValue == "yozaxis")
{
theDatumPart = Prs3d_DatumParts_YOZAxis;
}
else if (aValue == "xozaxis")
{
theDatumPart = Prs3d_DatumParts_XOZAxis;
}
else if (aValue == "whole")
{
theDatumPart = Prs3d_DatumParts_None;
}
else
{
return false;
}
return true;
}
static void convertToDatumParts(const TCollection_AsciiString& theValue,
NCollection_List<Prs3d_DatumParts>& theParts)
{
TCollection_AsciiString aValue = theValue;
const int aSplitPos = theValue.Search("|");
Prs3d_DatumParts aPart = Prs3d_DatumParts_None;
if (aSplitPos > 0)
{
convertToDatumParts(theValue.SubString(aSplitPos + 1, theValue.Length()), theParts);
if (aSplitPos == 1) // first symbol
{
return;
}
aValue = theValue.SubString(1, aSplitPos - 1);
}
if (convertToDatumPart(aValue, aPart))
{
theParts.Append(aPart);
}
}
static bool convertToDatumAttribute(const TCollection_AsciiString& theValue,
Prs3d_DatumAttribute& theAttribute)
{
TCollection_AsciiString aValue = theValue;
aValue.LowerCase();
if (aValue == "xaxislength")
{
theAttribute = Prs3d_DatumAttribute_XAxisLength;
}
else if (aValue == "yaxislength")
{
theAttribute = Prs3d_DatumAttribute_YAxisLength;
}
else if (aValue == "zaxislength")
{
theAttribute = Prs3d_DatumAttribute_ZAxisLength;
}
else if (aValue == "tuberadiuspercent")
{
theAttribute = Prs3d_DatumAttribute_ShadingTubeRadiusPercent;
}
else if (aValue == "coneradiuspercent")
{
theAttribute = Prs3d_DatumAttribute_ShadingConeRadiusPercent;
}
else if (aValue == "conelengthpercent")
{
theAttribute = Prs3d_DatumAttribute_ShadingConeLengthPercent;
}
else if (aValue == "originradiuspercent")
{
theAttribute = Prs3d_DatumAttribute_ShadingOriginRadiusPercent;
}
else if (aValue == "shadingnumberoffacettes")
{
theAttribute = Prs3d_DatumAttribute_ShadingNumberOfFacettes;
}
else
{
return false;
}
return true;
}
static void convertToDatumAttributes(const TCollection_AsciiString& theValue,
NCollection_List<Prs3d_DatumAttribute>& theAttributes)
{
TCollection_AsciiString aValue = theValue;
const int aSplitPos = theValue.Search("|");
Prs3d_DatumAttribute anAttribute = Prs3d_DatumAttribute_XAxisLength;
if (aSplitPos > 0)
{
convertToDatumAttributes(theValue.SubString(aSplitPos + 1, theValue.Length()), theAttributes);
if (aSplitPos == 1) // first symbol
{
return;
}
aValue = theValue.SubString(1, aSplitPos - 1);
}
if (convertToDatumAttribute(aValue, anAttribute))
{
theAttributes.Append(anAttribute);
}
}
static bool convertToDatumAxes(const TCollection_AsciiString& theValue,
Prs3d_DatumAxes& theDatumAxes)
{
TCollection_AsciiString aValue = theValue;
aValue.LowerCase();
if (aValue == "x")
{
theDatumAxes = Prs3d_DatumAxes_XAxis;
}
else if (aValue == "y")
{
theDatumAxes = Prs3d_DatumAxes_YAxis;
}
else if (aValue == "z")
{
theDatumAxes = Prs3d_DatumAxes_ZAxis;
}
else if (aValue == "xy")
{
theDatumAxes = Prs3d_DatumAxes_XYAxes;
}
else if (aValue == "zy")
{
theDatumAxes = Prs3d_DatumAxes_YZAxes;
}
else if (aValue == "xz")
{
theDatumAxes = Prs3d_DatumAxes_XZAxes;
}
else if (aValue == "xyz")
{
theDatumAxes = Prs3d_DatumAxes_XYZAxes;
}
else
{
return false;
}
return true;
}
static bool setTrihedronParams(int theArgsNb,
const char** theArgVec,
const occ::handle<AIS_Trihedron>& theTrihedron)
{
NCollection_DataMap<TCollection_AsciiString,
occ::handle<NCollection_HSequence<TCollection_AsciiString>>>
aMapOfArgs;
TCollection_AsciiString aParseKey;
for (int anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
{
TCollection_AsciiString anArg(theArgVec[anArgIt]);
if (anArg.Value(1) == '-' && !anArg.IsRealValue(true))
{
aParseKey = anArg;
aParseKey.Remove(1);
aParseKey.LowerCase();
std::string aKey = aParseKey.ToCString();
aMapOfArgs.Bind(aParseKey, new NCollection_HSequence<TCollection_AsciiString>());
continue;
}
if (aParseKey.IsEmpty())
{
continue;
}
aMapOfArgs(aParseKey)->Append(anArg);
}
// Check parameters
if ((aMapOfArgs.IsBound("xaxis") && !aMapOfArgs.IsBound("zaxis"))
|| (!aMapOfArgs.IsBound("xaxis") && aMapOfArgs.IsBound("zaxis")))
{
Message::SendFail("Syntax error: -xaxis and -zaxis parameters are to set together");
return false;
}
occ::handle<NCollection_HSequence<TCollection_AsciiString>> aValues;
occ::handle<Geom_Axis2Placement> aComponent = theTrihedron->Component();
if (aMapOfArgs.Find("origin", aValues))
{
aComponent->SetLocation(gp_Pnt(aValues->Value(1).RealValue(),
aValues->Value(2).RealValue(),
aValues->Value(3).RealValue()));
}
occ::handle<NCollection_HSequence<TCollection_AsciiString>> aXValues, aZValues;
if (aMapOfArgs.Find("xaxis", aXValues) && aMapOfArgs.Find("zaxis", aZValues))
{
gp_Dir aXDir(aXValues->Value(1).RealValue(),
aXValues->Value(2).RealValue(),
aXValues->Value(3).RealValue());
gp_Dir aZDir(aZValues->Value(1).RealValue(),
aZValues->Value(2).RealValue(),
aZValues->Value(3).RealValue());
if (!aZDir.IsNormal(aXDir, M_PI / 180.0))
{
Message::SendFail("Syntax error - parameters 'xaxis' and 'zaxis' are not applied as VectorX "
"is not normal to VectorZ");
return false;
}
aComponent->SetAx2(gp_Ax2(aComponent->Location(), aZDir, aXDir));
}
if (aMapOfArgs.Find("dispmode", aValues))
{
TCollection_AsciiString aValue(aValues->Value(1));
bool isWireframe = true;
if (aValue.IsEqual("sh") || aValue.IsEqual("shading"))
{
isWireframe = false;
}
theTrihedron->SetDatumDisplayMode(isWireframe ? Prs3d_DM_WireFrame : Prs3d_DM_Shaded);
}
if (aMapOfArgs.Find("hidelabels", aValues))
{
bool toHideLabels = true;
if (aValues->Size() == 1)
{
Draw::ParseOnOff(aValues->First().ToCString(), toHideLabels);
}
else if (aValues->Size() != 0)
{
Message::SendFail("Syntax error: -hidelabels expects parameter 'on' or 'off' after");
return false;
}
if (!theTrihedron->Attributes()->HasOwnDatumAspect())
{
theTrihedron->Attributes()->SetDatumAspect(new Prs3d_DatumAspect());
}
theTrihedron->Attributes()->DatumAspect()->SetDrawLabels(!toHideLabels);
}
if (aMapOfArgs.Find("hidearrows", aValues))
{
bool toHideArrows = true;
if (aValues->Size() == 1)
{
Draw::ParseOnOff(aValues->First().ToCString(), toHideArrows);
}
else if (aValues->Size() != 0)
{
Message::SendFail("Syntax error: -hidearrows expects parameter 'on' or 'off' after");
return false;
}
if (!theTrihedron->Attributes()->HasOwnDatumAspect())
{
theTrihedron->Attributes()->SetDatumAspect(new Prs3d_DatumAspect());
}
theTrihedron->Attributes()->DatumAspect()->SetDrawArrows(!toHideArrows);
}
if (aMapOfArgs.Find("color", aValues))
{
NCollection_List<Prs3d_DatumParts> aParts;
if (aValues->Size() < 2)
{
Message::SendFail("Syntax error: -color wrong parameters");
return false;
}
convertToDatumParts(aValues->Value(1), aParts);
aValues->Remove(1); // datum part is processed
Quantity_Color aColor;
if (!convertToColor(aValues, aColor))
{
Message::SendFail("Syntax error: -color wrong parameters");
return false;
}
for (NCollection_List<Prs3d_DatumParts>::Iterator anIterator(aParts); anIterator.More();
anIterator.Next())
{
Prs3d_DatumParts aDatumPart = anIterator.Value();
if (aDatumPart == Prs3d_DatumParts_None)
{
theTrihedron->SetColor(aColor);
}
else
{
theTrihedron->SetDatumPartColor(aDatumPart, aColor);
}
}
}
if (aMapOfArgs.Find("textcolor", aValues))
{
Prs3d_DatumParts aDatumPart = Prs3d_DatumParts_None;
if (!aValues->IsEmpty() && convertToDatumPart(aValues->First(), aDatumPart)
&& aDatumPart >= Prs3d_DatumParts_XAxis && aDatumPart <= Prs3d_DatumParts_ZAxis)
{
aValues->Remove(1); // datum part is processed
}
Quantity_Color aColor;
if (!convertToColor(aValues, aColor))
{
Message::SendFail("Syntax error: -textcolor wrong parameters");
return false;
}
if (aDatumPart != Prs3d_DatumParts_None)
{
theTrihedron->SetTextColor(aDatumPart, aColor);
}
else
{
theTrihedron->SetTextColor(aColor);
}
}
if (aMapOfArgs.Find("arrowcolor", aValues))
{
Prs3d_DatumParts aDatumPart = Prs3d_DatumParts_None;
if (!aValues->IsEmpty() && convertToDatumPart(aValues->First(), aDatumPart)
&& ((aDatumPart >= Prs3d_DatumParts_XArrow && aDatumPart <= Prs3d_DatumParts_ZArrow)
|| (aDatumPart >= Prs3d_DatumParts_XAxis && aDatumPart <= Prs3d_DatumParts_ZAxis)))
{
aValues->Remove(1); // datum part is processed
}
Quantity_Color aColor;
if (!convertToColor(aValues, aColor))
{
Message::SendFail("Syntax error: -arrowcolor wrong parameters");
return false;
}
if (aDatumPart != Prs3d_DatumParts_None)
{
Prs3d_DatumParts anArrowPart = Prs3d_DatumAspect::ArrowPartForAxis(aDatumPart);
theTrihedron->SetArrowColor(anArrowPart, aColor);
}
else
{
theTrihedron->SetArrowColor(aColor);
}
}
if (aMapOfArgs.Find("attribute", aValues))
{
NCollection_List<Prs3d_DatumAttribute> anAttributes;
if (aValues->Size() != 2)
{
Message::SendFail("Syntax error: -attribute wrong parameters");
return false;
}
convertToDatumAttributes(aValues->Value(1), anAttributes);
if (!theTrihedron->Attributes()->HasOwnDatumAspect())
{
theTrihedron->Attributes()->SetDatumAspect(new Prs3d_DatumAspect());
}
for (NCollection_List<Prs3d_DatumAttribute>::Iterator anIterator(anAttributes);
anIterator.More();
anIterator.Next())
{
theTrihedron->Attributes()->DatumAspect()->SetAttribute(anIterator.Value(),
aValues->Value(2).RealValue());
}
}
if (aMapOfArgs.Find("priority", aValues))
{
Prs3d_DatumParts aDatumPart;
if (aValues->Size() < 2 || !convertToDatumPart(aValues->Value(1), aDatumPart))
{
Message::SendFail("Syntax error: -priority wrong parameters");
return false;
}
theTrihedron->SetSelectionPriority(aDatumPart, aValues->Value(2).IntegerValue());
}
if (aMapOfArgs.Find("labels", aValues) || aMapOfArgs.Find("label", aValues))
{
Prs3d_DatumParts aDatumPart = Prs3d_DatumParts_None;
if (aValues->Size() >= 2 && convertToDatumPart(aValues->Value(1), aDatumPart)
&& aDatumPart >= Prs3d_DatumParts_XAxis
&& aDatumPart <= Prs3d_DatumParts_ZAxis) // labels are set to axes only
{
theTrihedron->SetLabel(aDatumPart, aValues->Value(2));
}
else
{
Message::SendFail("Syntax error: -labels wrong parameters");
return false;
}
}
if (aMapOfArgs.Find("drawaxes", aValues))
{
Prs3d_DatumAxes aDatumAxes = Prs3d_DatumAxes_XAxis;
if (aValues->Size() < 1 || !convertToDatumAxes(aValues->Value(1), aDatumAxes))
{
Message::SendFail("Syntax error: -drawaxes wrong parameters");
return false;
}
if (!theTrihedron->Attributes()->HasOwnDatumAspect())
{
theTrihedron->Attributes()->SetDatumAspect(new Prs3d_DatumAspect());
}
theTrihedron->Attributes()->DatumAspect()->SetDrawDatumAxes(aDatumAxes);
}
return true;
}
//! Auxiliary function to parse font aspect style argument
static bool parseFontStyle(const TCollection_AsciiString& theArg, Font_FontAspect& theAspect)
{
if (theArg == "regular" || *theArg.ToCString() == 'r')
{
theAspect = Font_FA_Regular;
return true;
}
else if (theArg == "bolditalic" || theArg == "bold-italic" || theArg == "italic-bold"
|| theArg == "italicbold")
{
theAspect = Font_FA_BoldItalic;
return true;
}
else if (theArg == "bold" || *theArg.ToCString() == 'b')
{
theAspect = Font_FA_Bold;
return true;
}
else if (theArg == "italic" || *theArg.ToCString() == 'i')
{
theAspect = Font_FA_Italic;
return true;
}
return false;
}
//! Auxiliary function to parse font strict level argument
static int parseFontStrictLevel(const int theArgNb,
const char** theArgVec,
Font_StrictLevel& theLevel)
{
if (theArgNb >= 1)
{
TCollection_AsciiString anArg(theArgVec[0]);
anArg.LowerCase();
if (anArg == "any")
{
theLevel = Font_StrictLevel_Any;
return 1;
}
else if (anArg == "aliases")
{
theLevel = Font_StrictLevel_Aliases;
return 1;
}
else if (anArg == "strict")
{
theLevel = Font_StrictLevel_Strict;
return 1;
}
}
theLevel = Font_StrictLevel_Strict;
return 0;
}
} // namespace
//==============================================================================
// function : Vtrihedron 2d
// purpose : Create a plane with a 2D trihedron from a faceselection
// Draw arg : vtri2d name
//==============================================================================
static int VTrihedron2D(Draw_Interpretor& /*theDI*/, int theArgsNum, const char** theArgVec)
{
if (ViewerTest::CurrentView().IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (theArgsNum != 2)
{
Message::SendFail() << "Syntax error: wrong number of arguments.";
return 1;
}
NCollection_List<TopoDS_Shape> aShapes;
ViewerTest::GetSelectedShapes(aShapes);
if (aShapes.Extent() != 1)
{
Message::SendFail("Error: wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape& aShape = aShapes.First();
TopoDS_Face aFace = TopoDS::Face(aShape);
TopExp_Explorer aFaceExp(aFace, TopAbs_EDGE);
TopoDS_Edge anEdge0 = TopoDS::Edge(aFaceExp.Current());
gp_Pnt A, B, C;
if (aFaceExp.More())
{
aFaceExp.Next();
TopoDS_Edge anEdge1 = TopoDS::Edge(aFaceExp.Current());
BRepAdaptor_Curve aCurve0(anEdge0);
BRepAdaptor_Curve aCurve1(anEdge1);
A = aCurve1.Value(0.1);
B = aCurve1.Value(0.9);
C = aCurve0.Value(0.5);
}
else
{
BRepAdaptor_Curve aCurve0(anEdge0);
A = aCurve0.Value(0.1);
B = aCurve0.Value(0.9);
C = aCurve0.Value(0.5);
}
GC_MakePlane aMkPlane(A, B, C);
occ::handle<AIS_PlaneTrihedron> anAISPlaneTri = new AIS_PlaneTrihedron(aMkPlane.Value());
TCollection_AsciiString aName(theArgVec[1]);
VDisplayAISObject(aName, anAISPlaneTri);
return 0;
}
//=================================================================================================
static int VTrihedron(Draw_Interpretor&, int theArgsNb, const char** theArgVec)
{
if (ViewerTest::CurrentView().IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (theArgsNb < 2)
{
Message::SendFail("Syntax error: the wrong number of input parameters");
return 1;
}
TCollection_AsciiString aName(theArgVec[1]);
bool toUpdate = true;
NCollection_DataMap<TCollection_AsciiString, double> aRealParams;
NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
occ::handle<AIS_Trihedron> aTrihedron;
occ::handle<AIS_InteractiveObject> anObject;
if (GetMapOfAIS().Find2(aName, anObject))
{
aTrihedron = occ::down_cast<AIS_Trihedron>(anObject);
if (aTrihedron.IsNull())
{
Message::SendFail("Syntax error: no trihedron with this name");
return 1;
}
}
else
{
occ::handle<Geom_Axis2Placement> aPlacement =
new Geom_Axis2Placement(gp_Pnt(0.0, 0.0, 0.0), gp::DZ(), gp::DX());
aTrihedron = new AIS_Trihedron(aPlacement);
}
if (!setTrihedronParams(theArgsNb, theArgVec, aTrihedron))
{
return 1;
}
// Redisplay a dimension after parameter changing.
if (ViewerTest::GetAISContext()->IsDisplayed(aTrihedron))
{
ViewerTest::GetAISContext()->Redisplay(aTrihedron, toUpdate);
}
else
{
VDisplayAISObject(theArgVec[1], aTrihedron);
}
return 0;
}
//==============================================================================
// function : VSize
// author : ege
// purpose : Change the size of a named or selected trihedron
// if no name : it affects the trihedrons which are selected otherwise nothing is donne
// if no value, the value is set at 100 by default
// Draw arg : vsize [name] [size]
//==============================================================================
static int VSize(Draw_Interpretor& di, int argc, const char** argv)
{
if (TheAISContext().IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
TCollection_AsciiString aName;
double aSize = 0.0;
switch (argc)
{
case 1: {
aSize = 100;
break;
}
case 2: {
aSize = Draw::Atof(argv[1]);
break;
}
case 3: {
aName = argv[1];
aSize = Draw::Atof(argv[2]);
break;
}
default: {
di << "Syntax error";
return 1;
}
}
NCollection_Sequence<occ::handle<AIS_Trihedron>> aTrihedrons;
if (!aName.IsEmpty())
{
occ::handle<AIS_InteractiveObject> aShape;
if (GetMapOfAIS().Find2(aName, aShape))
{
if (occ::handle<AIS_Trihedron> aTrihedron = occ::down_cast<AIS_Trihedron>(aShape))
{
aTrihedrons.Append(aTrihedron);
}
else
{
di << "Syntax error: " << aName << " is not a trihedron";
return 1;
}
}
}
else if (TheAISContext()->NbSelected() > 0)
{
for (NCollection_DoubleMap<occ::handle<AIS_InteractiveObject>,
TCollection_AsciiString>::Iterator it(GetMapOfAIS());
it.More();
it.Next())
{
const occ::handle<AIS_InteractiveObject>& aShape = it.Key1();
if (!aShape.IsNull() && TheAISContext()->IsSelected(aShape))
{
if (occ::handle<AIS_Trihedron> aTrihedron = occ::down_cast<AIS_Trihedron>(aShape))
{
aTrihedrons.Append(aTrihedron);
}
}
}
}
for (NCollection_Sequence<occ::handle<AIS_Trihedron>>::Iterator anObjIter(aTrihedrons);
anObjIter.More();
anObjIter.Next())
{
const occ::handle<AIS_Trihedron>& aTrihedron = anObjIter.Value();
Quantity_Color aColor = Quantity_NOC_BLACK;
const bool hasColor = aTrihedron->HasColor();
if (hasColor)
{
aTrihedron->Color(aColor);
}
aTrihedron->SetSize(aSize);
if (hasColor)
{
aTrihedron->SetColor(aColor);
}
else
{
aTrihedron->UnsetColor();
}
TheAISContext()->Redisplay(aTrihedron, false);
}
if (!aTrihedrons.IsEmpty())
{
TheAISContext()->UpdateCurrentViewer();
}
return 0;
}
//==============================================================================
//==============================================================================
// function : VPlaneTrihedron
// purpose : Create a plane from a trihedron selection. If no arguments are set, the default
// Draw arg : vplanetri name
//==============================================================================
#include <AIS_Plane.hxx>
static int VPlaneTrihedron(Draw_Interpretor& di, int argc, const char** argv)
{
// Verification des arguments
if (argc != 2)
{
di << argv[0] << " error\n";
return 1;
}
if (TheAISContext().IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (TheAISContext()->NbSelected() != 1)
{
Message::SendFail("Error: Wrong number of selected shapes.");
return 1;
}
TheAISContext()->InitSelected();
occ::handle<AIS_InteractiveObject> aTest = TheAISContext()->SelectedInteractive();
occ::handle<AIS_Plane> aPlane = occ::down_cast<AIS_Plane>(aTest);
if (aPlane.IsNull())
{
Message::SendFail("Error: Selected shape is not a plane.");
return 1;
}
VDisplayAISObject(argv[1], aPlane);
return 0;
}
//==============================================================================
// Fonction First click 2de click
//
// vaxis vertex vertex
// edge None
// vaxispara edge vertex
// vaxisortho edge Vertex
// vaxisinter Face Face
//==============================================================================
//==============================================================================
// function : VAxisBuilder
// purpose :
// Draw arg : vaxis AxisName Xa Ya Za Xb Yb Zb
//==============================================================================
#include <TopoDS_Edge.hxx>
#include <Geom_Line.hxx>
static int VAxisBuilder(Draw_Interpretor& di, int argc, const char** argv)
{
// Declarations
bool HasArg;
TCollection_AsciiString name;
// Verification
if (argc < 2 || argc > 8)
{
di << " Syntaxe error\n";
return 1;
}
HasArg = argc == 8;
name = argv[1];
NCollection_List<TopoDS_Shape> aShapes;
ViewerTest::GetSelectedShapes(aShapes);
// Cas ou il y a des arguments
// Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Line from Geom)
if (HasArg)
{
double coord[6];
for (int i = 0; i <= 5; i++)
{
coord[i] = Draw::Atof(argv[2 + i]);
}
gp_Pnt p1(coord[0], coord[1], coord[2]), p2(coord[3], coord[4], coord[5]);
gp_Vec myVect(p1, p2);
occ::handle<Geom_Line> myLine = new Geom_Line(p1, myVect);
occ::handle<AIS_Axis> TheAxis = new AIS_Axis(myLine);
GetMapOfAIS().Bind(TheAxis, name);
TheAISContext()->Display(TheAxis, true);
}
// Pas d'arguments
else
{
// fonction vaxis
// Purpose: Teste le constructeur AIS_Axis::AIS_Axis (x:Axis1Placement from Geom)
if (!strcasecmp(argv[0], "vaxis"))
{
if (aShapes.Extent() != 2 && aShapes.Extent() != 1)
{
Message::SendFail("Error: Wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape& aShapeA = aShapes.First();
if (aShapeA.ShapeType() == TopAbs_VERTEX)
{
if (aShapes.Extent() != 2)
{
Message::SendFail("Error: Wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape& aShapeB = aShapes.Last();
if (aShapeB.ShapeType() != TopAbs_VERTEX)
{
Message::SendFail("Syntax error: You should select two vertices or one edge.");
return 1;
}
// Construction de l'axe
gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
gp_Vec V(A, B);
gp_Dir D(V);
occ::handle<Geom_Axis1Placement> OrigineAndVect = new Geom_Axis1Placement(A, D);
occ::handle<AIS_Axis> TheAxis = new AIS_Axis(OrigineAndVect);
GetMapOfAIS().Bind(TheAxis, name);
TheAISContext()->Display(TheAxis, true);
}
else
{
TopoDS_Edge ed = TopoDS::Edge(aShapeA);
TopoDS_Vertex Va, Vb;
TopExp::Vertices(ed, Va, Vb);
gp_Pnt A = BRep_Tool::Pnt(Va);
gp_Pnt B = BRep_Tool::Pnt(Vb);
gp_Vec V(A, B);
gp_Dir D(V);
occ::handle<Geom_Axis1Placement> OrigineAndVect = new Geom_Axis1Placement(A, D);
occ::handle<AIS_Axis> TheAxis = new AIS_Axis(OrigineAndVect);
GetMapOfAIS().Bind(TheAxis, name);
TheAISContext()->Display(TheAxis, true);
}
}
// Fonction axispara
// Purpose: Teste le constructeur AIS_Axis::AIS_Axis(x: Axis2Placement from Geom, y: TypeOfAxis
// from AIS)
else if (!strcasecmp(argv[0], "vaxispara"))
{
if (aShapes.Extent() != 2)
{
Message::SendFail("Error: Wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape& aShapeA = aShapes.First();
const TopoDS_Shape& aShapeB = aShapes.Last();
if (aShapeA.ShapeType() != TopAbs_EDGE || aShapeB.ShapeType() != TopAbs_VERTEX)
{
Message::SendFail("Syntax error: You should select face and then vertex.");
return 1;
}
TopoDS_Edge ed = TopoDS::Edge(aShapeA);
gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
TopoDS_Vertex Va, Vc;
TopExp::Vertices(ed, Va, Vc);
gp_Pnt A = BRep_Tool::Pnt(Va);
gp_Pnt C = BRep_Tool::Pnt(Vc);
gp_Vec V(A, C);
gp_Dir D(V);
occ::handle<Geom_Axis1Placement> OrigineAndVect = new Geom_Axis1Placement(B, D);
occ::handle<AIS_Axis> TheAxis = new AIS_Axis(OrigineAndVect);
GetMapOfAIS().Bind(TheAxis, name);
TheAISContext()->Display(TheAxis, true);
}
// Fonction axisortho
else
{
if (aShapes.Extent() != 2)
{
Message::SendFail("Error: Wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape& aShapeA = aShapes.First();
const TopoDS_Shape& aShapeB = aShapes.Last();
if (aShapeA.ShapeType() != TopAbs_EDGE || aShapeB.ShapeType() != TopAbs_VERTEX)
{
Message::SendFail("Syntax error: You should select face and then vertex.");
return 1;
}
// Construction de l'axe
TopoDS_Edge ed = TopoDS::Edge(aShapeA);
gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
TopoDS_Vertex Va, Vc;
TopExp::Vertices(ed, Va, Vc);
gp_Pnt A = BRep_Tool::Pnt(Va);
gp_Pnt C = BRep_Tool::Pnt(Vc);
gp_Pnt E(A.Y() + A.Z() - C.Y() - C.Z(), C.X() - A.X(), C.X() - A.X());
gp_Vec V(A, E);
gp_Dir D(V);
occ::handle<Geom_Axis1Placement> OrigineAndVect = new Geom_Axis1Placement(B, D);
occ::handle<AIS_Axis> TheAxis = new AIS_Axis(OrigineAndVect);
GetMapOfAIS().Bind(TheAxis, name);
TheAISContext()->Display(TheAxis, true);
}
}
return 0;
}
//==============================================================================
// Fonction First click Result
//
// vpoint vertex AIS_Point=Vertex
// edge AIS_Point=Middle of the edge
//==============================================================================
//=================================================================================================
#include <AIS_Point.hxx>
#include <Geom_CartesianPoint.hxx>
static int VPointBuilder(Draw_Interpretor&, int theArgNb, const char** theArgVec)
{
TCollection_AsciiString aName;
gp_Pnt aPnt(RealLast(), 0.0, 0.0);
bool is2d = false, isNoSel = false;
for (int anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
TCollection_AsciiString anArg(theArgVec[anArgIter]);
anArg.LowerCase();
if (anArg == "-2d")
{
is2d = true;
}
else if (anArg == "-nosel" || anArg == "-noselection")
{
isNoSel = true;
}
else if (aName.IsEmpty())
{
aName = theArgVec[anArgIter];
}
else if (aPnt.X() == RealLast() && anArgIter + 1 < theArgNb
&& Draw::ParseReal(theArgVec[anArgIter + 0], aPnt.ChangeCoord().ChangeCoord(1))
&& Draw::ParseReal(theArgVec[anArgIter + 1], aPnt.ChangeCoord().ChangeCoord(2)))
{
if (anArgIter + 2 < theArgNb && TCollection_AsciiString(theArgVec[anArgIter + 2]) != "-2d"
&& Draw::ParseReal(theArgVec[anArgIter + 2], aPnt.ChangeCoord().ChangeCoord(3)))
{
anArgIter += 2;
}
else
{
anArgIter += 1;
}
}
else
{
Message::SendFail() << "Syntax error at argument '" << anArg << "'\n";
return 1;
}
}
if (aPnt.X() == RealLast())
{
NCollection_List<TopoDS_Shape> aShapes;
ViewerTest::GetSelectedShapes(aShapes);
TopoDS_Shape aShapeA;
if (aShapes.Extent() == 1)
{
aShapeA = aShapes.First();
}
switch (!aShapeA.IsNull() ? aShapeA.ShapeType() : TopAbs_SHAPE)
{
case TopAbs_VERTEX: {
aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
break;
}
case TopAbs_EDGE: // edge middle point
{
const TopoDS_Edge& anEdge = TopoDS::Edge(aShapeA);
TopoDS_Vertex aVertPair[2];
TopExp::Vertices(anEdge, aVertPair[0], aVertPair[1]);
const gp_Pnt A = BRep_Tool::Pnt(aVertPair[0]);
const gp_Pnt B = BRep_Tool::Pnt(aVertPair[1]);
aPnt = (A.XYZ() + B.XYZ()) / 2;
break;
}
default: {
Message::SendFail() << "Error: Wrong number of selected shapes.\n"
<< "\tYou should select one edge or vertex.";
return 1;
}
}
}
if (is2d)
{
aPnt.SetY(-aPnt.Y());
}
occ::handle<Geom_CartesianPoint> aGeomPoint = new Geom_CartesianPoint(aPnt);
occ::handle<AIS_Point> aPointPrs = new AIS_Point(aGeomPoint);
if (is2d)
{
aPointPrs->SetTransformPersistence(
new Graphic3d_TransformPers(Graphic3d_TMF_2d, Aspect_TOTP_LEFT_UPPER));
aPointPrs->SetZLayer(Graphic3d_ZLayerId_TopOSD);
}
ViewerTest::Display(aName, aPointPrs);
if (isNoSel)
{
ViewerTest::GetAISContext()->Deactivate(aPointPrs);
}
return 0;
}
//==============================================================================
// Function 1st click 2de click 3de click
// vplane Vertex Vertex Vertex
// Vertex Edge
// Edge Vertex
// Face
// vplanepara Face Vertex
// Vertex Face
// vplaneortho Face Edge
// Edge Face
//==============================================================================
//==============================================================================
// function : VPlaneBuilder
// purpose : Build an AIS_Plane from selected entities or Named AIS components
// Draw arg : vplane PlaneName [AxisName] [PointName] [TypeOfSensitivity]
// [PointName] [PointName] [PointName] [TypeOfSensitivity]
// [PlaneName] [PointName] [TypeOfSensitivity]
//==============================================================================
static int VPlaneBuilder(Draw_Interpretor& /*di*/, int argc, const char** argv)
{
// Declarations
bool hasArg;
TCollection_AsciiString aName;
// Verification
if (argc < 2 || argc > 6)
{
Message::SendFail("Syntax error: wrong number of arguments");
return 1;
}
hasArg = argc == 6 || argc == 5 || argc == 4;
aName = argv[1];
// There are some arguments
if (hasArg)
{
occ::handle<AIS_InteractiveObject> aShapeA;
if (!GetMapOfAIS().Find2(argv[2], aShapeA))
{
Message::SendFail("Syntax error: 1st name is not displayed");
return 1;
}
// The first argument is an AIS_Point
if (!aShapeA.IsNull() && aShapeA->Type() == AIS_KindOfInteractive_Datum
&& aShapeA->Signature() == 1)
{
// The second argument must also be an AIS_Point
occ::handle<AIS_InteractiveObject> aShapeB;
if (argc < 5 || !GetMapOfAIS().Find2(argv[3], aShapeB))
{
Message::SendFail("Syntax error: 2nd name is not displayed");
return 1;
}
// If B is not an AIS_Point
if (aShapeB.IsNull() || aShapeB->Type() != AIS_KindOfInteractive_Datum
|| aShapeB->Signature() != 1)
{
Message::SendFail("Syntax error: 2nd object is expected to be an AIS_Point");
return 1;
}
// The third object is an AIS_Point
occ::handle<AIS_InteractiveObject> aShapeC;
if (!GetMapOfAIS().Find2(argv[4], aShapeC))
{
Message::SendFail("Syntax error: 3d name is not displayed");
return 1;
}
// If C is not an AIS_Point
if (aShapeC.IsNull() || aShapeC->Type() != AIS_KindOfInteractive_Datum
|| aShapeC->Signature() != 1)
{
Message::SendFail("Syntax error: 3d object is expected to be an AIS_Point");
return 1;
}
// Treatment of objects A, B, C
// Downcast an AIS_IO to AIS_Point
occ::handle<AIS_Point> anAISPointA = occ::down_cast<AIS_Point>(aShapeA);
occ::handle<AIS_Point> anAISPointB = occ::down_cast<AIS_Point>(aShapeB);
occ::handle<AIS_Point> anAISPointC = occ::down_cast<AIS_Point>(aShapeC);
occ::handle<Geom_CartesianPoint> aCartPointA =
occ::down_cast<Geom_CartesianPoint>(anAISPointA->Component());
occ::handle<Geom_CartesianPoint> aCartPointB =
occ::down_cast<Geom_CartesianPoint>(anAISPointB->Component());
occ::handle<Geom_CartesianPoint> aCartPointC =
occ::down_cast<Geom_CartesianPoint>(anAISPointC->Component());
// Verification that the three points are different
if (std::abs(aCartPointB->X() - aCartPointA->X()) <= Precision::Confusion()
&& std::abs(aCartPointB->Y() - aCartPointA->Y()) <= Precision::Confusion()
&& std::abs(aCartPointB->Z() - aCartPointA->Z()) <= Precision::Confusion())
{
// B=A
Message::SendFail("Error: same points");
return 1;
}
if (std::abs(aCartPointC->X() - aCartPointA->X()) <= Precision::Confusion()
&& std::abs(aCartPointC->Y() - aCartPointA->Y()) <= Precision::Confusion()
&& std::abs(aCartPointC->Z() - aCartPointA->Z()) <= Precision::Confusion())
{
// C=A
Message::SendFail("Error: same points");
return 1;
}
if (std::abs(aCartPointC->X() - aCartPointB->X()) <= Precision::Confusion()
&& std::abs(aCartPointC->Y() - aCartPointB->Y()) <= Precision::Confusion()
&& std::abs(aCartPointC->Z() - aCartPointB->Z()) <= Precision::Confusion())
{
// C=B
Message::SendFail("Error: same points");
return 1;
}
gp_Pnt A = aCartPointA->Pnt();
gp_Pnt B = aCartPointB->Pnt();
gp_Pnt C = aCartPointC->Pnt();
// Construction of AIS_Plane
GC_MakePlane MkPlane(A, B, C);
const occ::handle<Geom_Plane>& aGeomPlane = MkPlane.Value();
occ::handle<AIS_Plane> anAISPlane = new AIS_Plane(aGeomPlane);
GetMapOfAIS().Bind(anAISPlane, aName);
if (argc == 6)
{
int aType = Draw::Atoi(argv[5]);
if (aType != 0 && aType != 1)
{
Message::SendFail("Syntax error: wrong type of sensitivity.\n"
"Should be one of the following values:\n"
"0 - Interior\n"
"1 - Boundary");
return 1;
}
else
{
anAISPlane->SetTypeOfSensitivity(Select3D_TypeOfSensitivity(aType));
}
}
TheAISContext()->Display(anAISPlane, true);
}
// The first argument is an AIS_Axis
// Creation of a plane orthogonal to the axis through a point
else if (aShapeA->Type() == AIS_KindOfInteractive_Datum && aShapeA->Signature() == 2)
{
// The second argument should be an AIS_Point
occ::handle<AIS_InteractiveObject> aShapeB;
if (argc != 4 || !GetMapOfAIS().Find2(argv[3], aShapeB))
{
Message::SendFail("Syntax error: 2d name is not displayed");
return 1;
}
// If B is not an AIS_Point
if (aShapeB.IsNull() || aShapeB->Type() != AIS_KindOfInteractive_Datum
|| aShapeB->Signature() != 1)
{
Message::SendFail("Syntax error: 2d object is expected to be an AIS_Point");
return 1;
}
// Treatment of objects A and B
occ::handle<AIS_Axis> anAISAxisA = occ::down_cast<AIS_Axis>(aShapeA);
occ::handle<AIS_Point> anAISPointB = occ::down_cast<AIS_Point>(aShapeB);
occ::handle<Geom_Line> aGeomLineA = anAISAxisA->Component();
occ::handle<Geom_Point> aGeomPointB = anAISPointB->Component();
gp_Ax1 anAxis = aGeomLineA->Position();
occ::handle<Geom_CartesianPoint> aCartPointB =
occ::down_cast<Geom_CartesianPoint>(aGeomPointB);
gp_Dir D = anAxis.Direction();
gp_Pnt B = aCartPointB->Pnt();
// Construction of AIS_Plane
occ::handle<Geom_Plane> aGeomPlane = new Geom_Plane(B, D);
occ::handle<AIS_Plane> anAISPlane = new AIS_Plane(aGeomPlane, B);
GetMapOfAIS().Bind(anAISPlane, aName);
if (argc == 5)
{
int aType = Draw::Atoi(argv[4]);
if (aType != 0 && aType != 1)
{
Message::SendFail("Syntax error: wrong type of sensitivity!\n"
"Should be one of the following values:\n"
"0 - Interior\n"
"1 - Boundary");
return 1;
}
else
{
anAISPlane->SetTypeOfSensitivity(Select3D_TypeOfSensitivity(aType));
}
}
TheAISContext()->Display(anAISPlane, true);
}
// The first argument is an AIS_Plane
// Creation of a plane parallel to the plane passing through the point
else if (aShapeA->Type() == AIS_KindOfInteractive_Datum && aShapeA->Signature() == 7)
{
// The second argument should be an AIS_Point
occ::handle<AIS_InteractiveObject> aShapeB;
if (argc != 4 || !GetMapOfAIS().Find2(argv[3], aShapeB))
{
Message::SendFail("Syntax error: 2d name is not displayed");
return 1;
}
// B should be an AIS_Point
if (aShapeB.IsNull() || aShapeB->Type() != AIS_KindOfInteractive_Datum
|| aShapeB->Signature() != 1)
{
Message::SendFail("Syntax error: 2d object is expected to be an AIS_Point");
return 1;
}
// Treatment of objects A and B
occ::handle<AIS_Plane> anAISPlaneA = occ::down_cast<AIS_Plane>(aShapeA);
occ::handle<AIS_Point> anAISPointB = occ::down_cast<AIS_Point>(aShapeB);
occ::handle<Geom_Plane> aNewGeomPlane = anAISPlaneA->Component();
occ::handle<Geom_Point> aGeomPointB = anAISPointB->Component();
occ::handle<Geom_CartesianPoint> aCartPointB =
occ::down_cast<Geom_CartesianPoint>(aGeomPointB);
gp_Pnt B = aCartPointB->Pnt();
// Construction of an AIS_Plane
occ::handle<AIS_Plane> anAISPlane = new AIS_Plane(aNewGeomPlane, B);
GetMapOfAIS().Bind(anAISPlane, aName);
if (argc == 5)
{
int aType = Draw::Atoi(argv[4]);
if (aType != 0 && aType != 1)
{
Message::SendFail("Syntax error: wrong type of sensitivity!\n"
"Should be one of the following values:\n"
"0 - Interior\n"
"1 - Boundary");
return 1;
}
else
{
anAISPlane->SetTypeOfSensitivity(Select3D_TypeOfSensitivity(aType));
}
}
TheAISContext()->Display(anAISPlane, true);
}
// Error
else
{
Message::SendFail("Syntax error: 1st object is not an AIS");
return 1;
}
}
// There are no arguments
else
{
NCollection_List<TopoDS_Shape> aShapes;
ViewerTest::GetSelectedShapes(aShapes);
// Function vplane
// Test the constructor AIS_Plane::AIS_Plane(Geom_Plane, bool )
if (!strcasecmp(argv[0], "vplane"))
{
if (aShapes.Extent() < 1 || aShapes.Extent() > 3)
{
Message::SendFail()
<< "Error: Wrong number of selected shapes.\n"
<< "\tYou should one of variant: face, edge and vertex or three vertices.";
return 1;
}
const TopoDS_Shape& aShapeA = aShapes.First();
if (aShapeA.ShapeType() == TopAbs_VERTEX)
{
if (aShapes.Extent() == 2)
{
const TopoDS_Shape& aShapeB = aShapes.Last();
if (aShapeB.ShapeType() != TopAbs_EDGE)
{
Message::SendFail("Syntax error: Together with vertex should be edge.");
return 1;
}
// Verify that the vertex is not on the edge ShapeB
TopoDS_Edge anEdgeB = TopoDS::Edge(aShapeB);
TopoDS_Vertex aVertA = TopoDS::Vertex(aShapeA);
BRepExtrema_ExtPC OrthoProj(aVertA, anEdgeB);
if (OrthoProj.SquareDistance(1) < Precision::Approximation())
{
// The vertex is on the edge
Message::SendFail("Error: point is on the edge");
return 1;
}
else
{
gp_Pnt A = BRep_Tool::Pnt(aVertA);
TopoDS_Vertex aVBa, aVBb;
TopExp::Vertices(anEdgeB, aVBa, aVBb);
gp_Pnt aBa = BRep_Tool::Pnt(aVBa);
gp_Pnt aBb = BRep_Tool::Pnt(aVBb);
GC_MakePlane MkPlane(A, aBa, aBb);
const occ::handle<Geom_Plane>& aGeomPlane = MkPlane.Value();
occ::handle<AIS_Plane> anAISPlane = new AIS_Plane(aGeomPlane);
GetMapOfAIS().Bind(anAISPlane, aName);
TheAISContext()->Display(anAISPlane, true);
}
}
else if (aShapes.Extent() == 3)
{
NCollection_List<TopoDS_Shape>::Iterator anIter(aShapes);
anIter.Next();
const TopoDS_Shape& aShapeB = anIter.Value();
anIter.Next();
const TopoDS_Shape& aShapeC = anIter.Value();
if (aShapeB.ShapeType() != TopAbs_VERTEX || aShapeC.ShapeType() != TopAbs_VERTEX)
{
Message::SendFail(
"Syntax error: You should one of variant: face, edge and vertex or three vertices.");
return 1;
}
gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(aShapeC));
GC_MakePlane MkPlane(A, B, C);
const occ::handle<Geom_Plane>& aGeomPlane = MkPlane.Value();
occ::handle<AIS_Plane> anAISPlane = new AIS_Plane(aGeomPlane);
GetMapOfAIS().Bind(anAISPlane, aName);
TheAISContext()->Display(anAISPlane, true);
}
else
{
Message::SendFail(
"Syntax error: You should one of variant: face, edge and vertex or three vertices.");
return 1;
}
}
else if (aShapeA.ShapeType() == TopAbs_EDGE)
{
if (aShapes.Extent() != 2)
{
Message::SendFail("Error: wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape& aShapeB = aShapes.Last();
if (aShapeB.ShapeType() != TopAbs_VERTEX)
{
Message::SendFail("Syntax error: Together with edge should be vertex.");
return 1;
}
// Check that the vertex aShapeB is not on the edge
TopoDS_Edge anEdgeA = TopoDS::Edge(aShapeA);
TopoDS_Vertex aVertB = TopoDS::Vertex(aShapeB);
BRepExtrema_ExtPC OrthoProj(aVertB, anEdgeA);
if (OrthoProj.SquareDistance(1) < Precision::Approximation())
{
// The vertex is on the edge
Message::SendFail("Error point is on the edge");
return 1;
}
gp_Pnt B = BRep_Tool::Pnt(aVertB);
TopoDS_Vertex aVAa, aVAb;
TopExp::Vertices(anEdgeA, aVAa, aVAb);
gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
GC_MakePlane MkPlane(B, Aa, Ab);
const occ::handle<Geom_Plane>& aGeomPlane = MkPlane.Value();
occ::handle<AIS_Plane> anAISPlane = new AIS_Plane(aGeomPlane);
GetMapOfAIS().Bind(anAISPlane, aName);
TheAISContext()->Display(anAISPlane, true);
}
else if (aShapeA.ShapeType() == TopAbs_FACE)
{
TopoDS_Face aFace = TopoDS::Face(aShapeA);
BRepAdaptor_Surface aSurface(aFace, false);
if (aSurface.GetType() == GeomAbs_Plane)
{
gp_Pln aPlane = aSurface.Plane();
occ::handle<Geom_Plane> aGeomPlane = new Geom_Plane(aPlane);
occ::handle<AIS_Plane> anAISPlane = new AIS_Plane(aGeomPlane);
GetMapOfAIS().Bind(anAISPlane, aName);
TheAISContext()->Display(anAISPlane, true);
}
else
{
Message::SendFail("Error: surface is not Plane");
return 1;
}
}
else
{
Message::SendFail(
"Syntax error: You should one of variant: face, edge and vertex or three vertices");
return 1;
}
}
// Function vPlanePara
// ===================
// test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt)
else if (!strcasecmp(argv[0], "vplanepara"))
{
if (aShapes.Extent() != 2)
{
Message::SendFail("Error: Wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape* aShapeA = &aShapes.First();
const TopoDS_Shape* aShapeB = &aShapes.Last();
if (aShapeA->ShapeType() != TopAbs_VERTEX)
{
std::swap(aShapeA, aShapeB);
}
if (aShapeA->ShapeType() != TopAbs_VERTEX || aShapeB->ShapeType() != TopAbs_FACE)
{
Message::SendFail("Syntax error: you should select face and vertex.");
return 1;
}
gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(*aShapeA));
TopoDS_Face aFace = TopoDS::Face(*aShapeB);
BRepAdaptor_Surface aSurface(aFace, false);
if (aSurface.GetType() == GeomAbs_Plane)
{
gp_Pln aPlane = aSurface.Plane();
// Construct a plane parallel to aGeomPlane through A
aPlane.SetLocation(A);
occ::handle<Geom_Plane> aGeomPlane = new Geom_Plane(aPlane);
occ::handle<AIS_Plane> aAISPlane = new AIS_Plane(aGeomPlane, A);
GetMapOfAIS().Bind(aAISPlane, aName);
TheAISContext()->Display(aAISPlane, true);
}
else
{
Message::SendFail("Error: Built surface is not a plane.");
return 1;
}
}
// Function vplaneortho
// ====================
// test the constructor AIS_Plane::AIS_Plane(Geom_Plane,gp_Pnt,gp_Pnt,gp_Pnt)
else
{
if (aShapes.Extent() != 2)
{
Message::SendFail("Error: wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape* aShapeA = &aShapes.First();
const TopoDS_Shape* aShapeB = &aShapes.Last();
if (aShapeA->ShapeType() != TopAbs_EDGE)
{
std::swap(aShapeA, aShapeB);
}
if (aShapeA->ShapeType() != TopAbs_EDGE || aShapeB->ShapeType() != TopAbs_FACE)
{
Message::SendFail("Error: you should select edge and face.");
return 1;
}
// Construction of plane
TopoDS_Edge anEdgeA = TopoDS::Edge(*aShapeA);
TopoDS_Vertex aVAa, aVAb;
TopExp::Vertices(anEdgeA, aVAa, aVAb);
gp_Pnt Aa = BRep_Tool::Pnt(aVAa);
gp_Pnt Ab = BRep_Tool::Pnt(aVAb);
gp_Vec ab(Aa, Ab);
gp_Dir Dab(ab);
// Creation of rotation axis
gp_Ax1 aRotAxis(Aa, Dab);
TopoDS_Face aFace = TopoDS::Face(*aShapeB);
// The edge must be parallel to the face
BRepExtrema_ExtPF aHeightA(aVAa, aFace);
BRepExtrema_ExtPF aHeightB(aVAb, aFace);
// Compare to heights
if (fabs(sqrt(aHeightA.SquareDistance(1)) - sqrt(aHeightB.SquareDistance(1)))
> Precision::Confusion())
{
// the edge is not parallel to the face
Message::SendFail("Error: the edge is not parallel to the face");
return 1;
}
// the edge is OK
BRepAdaptor_Surface aSurface(aFace, false);
if (aSurface.GetType() == GeomAbs_Plane)
{
gp_Pln aPlane = aSurface.Plane();
// It rotates a half turn round the axis of rotation
aPlane.Rotate(aRotAxis, M_PI / 2);
occ::handle<Geom_Plane> aGeomPlane = new Geom_Plane(aPlane);
// constructed aGeomPlane parallel to a plane containing the edge (center mid-edge)
gp_Pnt aMiddle((Aa.X() + Ab.X()) / 2, (Aa.Y() + Ab.Y()) / 2, (Aa.Z() + Ab.Z()) / 2);
occ::handle<AIS_Plane> anAISPlane = new AIS_Plane(aGeomPlane, aMiddle);
GetMapOfAIS().Bind(anAISPlane, aName);
TheAISContext()->Display(anAISPlane, true);
}
else
{
Message::SendFail("Error: surface is not Plane");
return 1;
}
}
}
return 0;
}
//=================================================================================================
static int VChangePlane(Draw_Interpretor& /*theDi*/, int theArgsNb, const char** theArgVec)
{
occ::handle<AIS_InteractiveContext> aContextAIS = ViewerTest::GetAISContext();
if (aContextAIS.IsNull())
{
Message::SendFail("Error: no active viewer.");
return 1;
}
if (theArgsNb < 3 || theArgsNb > 11)
{
Message::SendFail("Syntax error: wrong number of arguments.");
return 1;
}
TCollection_AsciiString aName(theArgVec[1]);
occ::handle<AIS_Plane> aPlane =
GetMapOfAIS().IsBound2(aName) ? occ::down_cast<AIS_Plane>(GetMapOfAIS().Find2(aName)) : nullptr;
if (aPlane.IsNull())
{
Message::SendFail() << "Syntax error: there is no interactive plane with the given name '"
<< aName << "'.";
return 1;
}
double aCenterX = aPlane->Center().X();
double aCenterY = aPlane->Center().Y();
double aCenterZ = aPlane->Center().Z();
double aDirX = aPlane->Component()->Axis().Direction().X();
double aDirY = aPlane->Component()->Axis().Direction().Y();
double aDirZ = aPlane->Component()->Axis().Direction().Z();
double aSizeX = 0.0;
double aSizeY = 0.0;
bool aHasMinSize = aPlane->HasMinimumSize();
double aMinSizeY = 0.0;
aPlane->Size(aSizeX, aSizeY);
bool isUpdate = true;
TCollection_AsciiString aPName, aPValue;
for (int anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
{
const TCollection_AsciiString anArg = theArgVec[anArgIt];
TCollection_AsciiString anArgCase = anArg;
anArgCase.UpperCase();
if (ViewerTest::SplitParameter(anArg, aPName, aPValue))
{
aPName.UpperCase();
if (aPName.IsEqual("X"))
{
aCenterX = aPValue.RealValue();
}
else if (aPName.IsEqual("Y"))
{
aCenterY = aPValue.RealValue();
}
else if (aPName.IsEqual("Z"))
{
aCenterZ = aPValue.RealValue();
}
else if (aPName.IsEqual("DX"))
{
aDirX = aPValue.RealValue();
}
else if (aPName.IsEqual("DY"))
{
aDirY = aPValue.RealValue();
}
else if (aPName.IsEqual("DZ"))
{
aDirZ = aPValue.RealValue();
}
else if (aPName.IsEqual("SX"))
{
aSizeX = aPValue.RealValue();
}
else if (aPName.IsEqual("SY"))
{
aSizeY = aPValue.RealValue();
}
else if (aPName.IsEqual("MINSIZE"))
{
aHasMinSize = true;
aMinSizeY = aPValue.RealValue();
}
}
else if (anArg.IsEqual("NOUPDATE"))
{
isUpdate = false;
}
}
gp_Dir aDirection(aDirX, aDirY, aDirZ);
gp_Pnt aCenterPnt(aCenterX, aCenterY, aCenterZ);
aPlane->SetCenter(aCenterPnt);
aPlane->SetComponent(new Geom_Plane(aCenterPnt, aDirection));
aPlane->SetSize(aSizeX, aSizeY);
if (aHasMinSize)
{
aPlane->SetMinimumSize(aMinSizeY);
}
else if (aPlane->HasMinimumSize())
{
aPlane->UnsetMinimumSize();
}
aContextAIS->Update(aPlane, isUpdate);
return 0;
}
//==============================================================================
// Fonction vline
// --------------- Uniquement par parametre. Pas de selection dans le viewer.
//==============================================================================
//==============================================================================
// function : VLineBuilder
// purpose : Build an AIS_Line
// Draw arg : vline LineName [AIS_PointName] [AIS_PointName]
// [Xa] [Ya] [Za] [Xb] [Yb] [Zb]
//==============================================================================
#include <AIS_Line.hxx>
static int VLineBuilder(Draw_Interpretor& di, int argc, const char** argv)
{
if (argc == 4) // parameters: AIS_Point AIS_Point
{
occ::handle<AIS_InteractiveObject> aShapeA, aShapeB;
GetMapOfAIS().Find2(argv[2], aShapeA);
GetMapOfAIS().Find2(argv[3], aShapeB);
occ::handle<AIS_Point> anAISPointA = occ::down_cast<AIS_Point>(aShapeA);
occ::handle<AIS_Point> anAISPointB = occ::down_cast<AIS_Point>(aShapeB);
if (anAISPointA.IsNull() || anAISPointB.IsNull())
{
di << "vline error: wrong type of arguments\n";
return 1;
}
occ::handle<Geom_Point> aGeomPointBA = anAISPointA->Component();
occ::handle<Geom_CartesianPoint> aCartPointA =
occ::down_cast<Geom_CartesianPoint>(aGeomPointBA);
occ::handle<Geom_Point> aGeomPointB = anAISPointB->Component();
occ::handle<Geom_CartesianPoint> aCartPointB = occ::down_cast<Geom_CartesianPoint>(aGeomPointB);
if (aCartPointB->X() == aCartPointA->X() && aCartPointB->Y() == aCartPointA->Y()
&& aCartPointB->Z() == aCartPointA->Z())
{
// B=A
di << "vline error: same points\n";
return 1;
}
occ::handle<AIS_Line> anAISLine = new AIS_Line(aCartPointA, aCartPointB);
GetMapOfAIS().Bind(anAISLine, argv[1]);
TheAISContext()->Display(anAISLine, true);
}
else if (argc == 8) // parametres 6 reals
{
double aCoord[6] = {};
for (int i = 0; i <= 2; ++i)
{
aCoord[i] = Draw::Atof(argv[2 + i]);
aCoord[i + 3] = Draw::Atof(argv[5 + i]);
}
occ::handle<Geom_CartesianPoint> aCartPointA =
new Geom_CartesianPoint(aCoord[0], aCoord[1], aCoord[2]);
occ::handle<Geom_CartesianPoint> aCartPointB =
new Geom_CartesianPoint(aCoord[3], aCoord[4], aCoord[5]);
occ::handle<AIS_Line> anAISLine = new AIS_Line(aCartPointA, aCartPointB);
GetMapOfAIS().Bind(anAISLine, argv[1]);
TheAISContext()->Display(anAISLine, true);
}
else if (argc == 2) // selection in 3D viewer
{
NCollection_List<TopoDS_Shape> aShapes;
ViewerTest::GetSelectedShapes(aShapes);
if (aShapes.Extent() != 2)
{
Message::SendFail("Error: wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape& aShapeA = aShapes.First();
const TopoDS_Shape& aShapeB = aShapes.Last();
if (aShapeA.ShapeType() != TopAbs_VERTEX || aShapeB.ShapeType() != TopAbs_VERTEX)
{
Message::SendFail("Error: you should select two different vertex.");
return 1;
}
// Construction de la line
gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
occ::handle<Geom_CartesianPoint> aCartPointA = new Geom_CartesianPoint(A);
occ::handle<Geom_CartesianPoint> aCartPointB = new Geom_CartesianPoint(B);
occ::handle<AIS_Line> anAISLine = new AIS_Line(aCartPointA, aCartPointB);
GetMapOfAIS().Bind(anAISLine, argv[1]);
TheAISContext()->Display(anAISLine, true);
}
else
{
di << "Syntax error: wrong number of arguments";
return 1;
}
return 0;
}
//==============================================================================
// class : FilledCircle
// purpose : creates filled circle based on AIS_InteractiveObject
// and Geom_Circle.
// This class is used to check method Matches() of class
// Select3D_SensitiveCircle with member myFillStatus = true,
// because none of AIS classes provides creation of
// Select3D_SensitiveCircle with member myFillStatus = true
// (look method ComputeSelection() )
//==============================================================================
occ::handle<Geom_Circle> CreateCircle(gp_Pnt theCenter, double theRadius)
{
gp_Ax2 anAxes(theCenter, gp_Dir(gp_Vec(0., 0., 1.)));
gp_Circ aCirc(anAxes, theRadius);
occ::handle<Geom_Circle> aCircle = new Geom_Circle(aCirc);
return aCircle;
}
class FilledCircle : public AIS_InteractiveObject
{
public:
// CASCADE RTTI
DEFINE_STANDARD_RTTI_INLINE(FilledCircle, AIS_InteractiveObject);
FilledCircle(const occ::handle<Geom_Circle>& theCircle,
const double theUStart,
const double theUEnd);
FilledCircle(const gp_Pnt& theCenter,
const double theRadius,
const double theUStart,
const double theUEnd);
private:
TopoDS_Face ComputeFace();
// Virtual methods implementation
void Compute(const occ::handle<PrsMgr_PresentationManager>& thePrsMgr,
const occ::handle<Prs3d_Presentation>& thePrs,
const int theMode) override;
void ComputeSelection(const occ::handle<SelectMgr_Selection>& theSel, const int theMode) override;
protected:
occ::handle<Geom_Circle> myCircle;
double myUStart;
double myUEnd;
bool myFilledStatus;
};
FilledCircle::FilledCircle(const occ::handle<Geom_Circle>& theCircle,
const double theUStart,
const double theUEnd)
: myCircle(theCircle),
myUStart(theUStart),
myUEnd(theUEnd),
myFilledStatus(true)
{
}
FilledCircle::FilledCircle(const gp_Pnt& theCenter,
const double theRadius,
const double theUStart,
const double theUEnd)
: FilledCircle(CreateCircle(theCenter, theRadius), theUStart, theUEnd)
{
}
TopoDS_Face FilledCircle::ComputeFace()
{
// Create edge from myCircle
BRepBuilderAPI_MakeEdge anEdgeMaker(myCircle->Circ(), myUStart, myUEnd);
TopoDS_Edge anEdge = anEdgeMaker.Edge();
// Create wire from anEdge
BRepBuilderAPI_MakeWire aWireMaker;
if (std::abs(std::abs(myUEnd - myUStart) - 2.0 * M_PI) > gp::Resolution())
{
TopoDS_Edge anEndCenterEdge =
BRepBuilderAPI_MakeEdge(myCircle->Value(myUEnd), myCircle->Location()).Edge();
TopoDS_Edge aStartCenterEdge =
BRepBuilderAPI_MakeEdge(myCircle->Location(), myCircle->Value(myUStart)).Edge();
aWireMaker = BRepBuilderAPI_MakeWire(anEdge, anEndCenterEdge, aStartCenterEdge);
}
else
{
aWireMaker = BRepBuilderAPI_MakeWire(anEdge);
}
TopoDS_Wire aWire = aWireMaker.Wire();
// Create face from aWire
BRepBuilderAPI_MakeFace aFaceMaker(aWire);
TopoDS_Face aFace = aFaceMaker.Face();
return aFace;
}
void FilledCircle::Compute(const occ::handle<PrsMgr_PresentationManager>&,
const occ::handle<Prs3d_Presentation>& thePrs,
const int theMode)
{
thePrs->Clear();
TopoDS_Face aFace = ComputeFace();
if (aFace.IsNull())
{
return;
}
if (theMode != 0)
{
return;
}
StdPrs_ShadedShape::Add(thePrs, aFace, myDrawer);
}
void FilledCircle::ComputeSelection(const occ::handle<SelectMgr_Selection>& theSelection,
const int /*theMode*/)
{
occ::handle<SelectMgr_EntityOwner> anEntityOwner = new SelectMgr_EntityOwner(this);
occ::handle<Select3D_SensitiveEntity> aSensitiveCircle;
if (std::abs(std::abs(myUEnd - myUStart) - 2.0 * M_PI) > gp::Resolution())
{
aSensitiveCircle =
new Select3D_SensitivePoly(anEntityOwner, myCircle->Circ(), myUStart, myUEnd, myFilledStatus);
}
else
{
aSensitiveCircle =
new Select3D_SensitiveCircle(anEntityOwner, myCircle->Circ(), myFilledStatus);
}
theSelection->Add(aSensitiveCircle);
}
//==============================================================================
// Fonction vcircle
// ----------------- Uniquement par parametre. Pas de selection dans le viewer.
//==============================================================================
//==============================================================================
// function : VCircleBuilder
// purpose : Build an AIS_Circle
// Draw arg : vcircle CircleName PlaneName PointName Radius IsFilled UStart UEnd
// PointName PointName PointName IsFilled UStart UEnd
//==============================================================================
void DisplayCircle(const occ::handle<Geom_Circle>& theGeomCircle,
const TCollection_AsciiString& theName,
const bool isFilled,
const double theUStart,
const double theUEnd)
{
occ::handle<AIS_InteractiveObject> aCircle;
if (isFilled)
{
aCircle = new FilledCircle(theGeomCircle, theUStart, theUEnd);
}
else
{
aCircle = new AIS_Circle(theGeomCircle, theUStart, theUEnd, false);
}
// Check if there is an object with given name
// and remove it from context
if (GetMapOfAIS().IsBound2(theName))
{
occ::handle<AIS_InteractiveObject> anInterObj = GetMapOfAIS().Find2(theName);
TheAISContext()->Remove(anInterObj, false);
GetMapOfAIS().UnBind2(theName);
}
// Bind the circle to its name
GetMapOfAIS().Bind(aCircle, theName);
// Display the circle
TheAISContext()->Display(aCircle, true);
}
static int VCircleBuilder(Draw_Interpretor& /*di*/, int argc, const char** argv)
{
if (argc > 8 || argc < 2)
{
Message::SendFail("Syntax error: wrong number of arguments");
return 1;
}
double anUStart = 0, anUEnd = M_PI * 2.0;
if (argc == 8)
{
anUStart = Draw::Atof(argv[6]) * M_PI / 180.0;
anUEnd = Draw::Atof(argv[7]) * M_PI / 180.0;
}
else if (argc == 4)
{
anUStart = Draw::Atof(argv[2]) * M_PI / 180.0;
anUEnd = Draw::Atof(argv[3]) * M_PI / 180.0;
}
if (argc == 6 || argc == 8)
{
TCollection_AsciiString aName(argv[1]);
bool isFilled = Draw::Atoi(argv[5]) != 0;
occ::handle<AIS_InteractiveObject> aShapeA, aShapeB;
GetMapOfAIS().Find2(argv[2], aShapeA);
GetMapOfAIS().Find2(argv[3], aShapeB);
// Arguments: AIS_Point AIS_Point AIS_Point
if (!aShapeA.IsNull() && !aShapeB.IsNull() && aShapeA->Type() == AIS_KindOfInteractive_Datum
&& aShapeA->Signature() == 1)
{
occ::handle<AIS_InteractiveObject> aShapeC;
GetMapOfAIS().Find2(argv[4], aShapeC);
occ::handle<AIS_Point> anAISPointA = occ::down_cast<AIS_Point>(aShapeA);
occ::handle<AIS_Point> anAISPointB = occ::down_cast<AIS_Point>(aShapeB);
occ::handle<AIS_Point> anAISPointC = occ::down_cast<AIS_Point>(aShapeC);
if (anAISPointA.IsNull() || anAISPointB.IsNull() || anAISPointC.IsNull())
{
Message::SendFail("Error: arguments are expected to be points");
return 1;
}
// Verify that the three points are different
occ::handle<Geom_CartesianPoint> aCartPointA =
occ::down_cast<Geom_CartesianPoint>(anAISPointA->Component());
occ::handle<Geom_CartesianPoint> aCartPointB =
occ::down_cast<Geom_CartesianPoint>(anAISPointB->Component());
occ::handle<Geom_CartesianPoint> aCartPointC =
occ::down_cast<Geom_CartesianPoint>(anAISPointC->Component());
// Test A=B
if (std::abs(aCartPointA->X() - aCartPointB->X()) <= Precision::Confusion()
&& std::abs(aCartPointA->Y() - aCartPointB->Y()) <= Precision::Confusion()
&& std::abs(aCartPointA->Z() - aCartPointB->Z()) <= Precision::Confusion())
{
Message::SendFail("Error: Same points");
return 1;
}
// Test A=C
if (std::abs(aCartPointA->X() - aCartPointC->X()) <= Precision::Confusion()
&& std::abs(aCartPointA->Y() - aCartPointC->Y()) <= Precision::Confusion()
&& std::abs(aCartPointA->Z() - aCartPointC->Z()) <= Precision::Confusion())
{
Message::SendFail("Error: Same points");
return 1;
}
// Test B=C
if (std::abs(aCartPointB->X() - aCartPointC->X()) <= Precision::Confusion()
&& std::abs(aCartPointB->Y() - aCartPointC->Y()) <= Precision::Confusion()
&& std::abs(aCartPointB->Z() - aCartPointC->Z()) <= Precision::Confusion())
{
Message::SendFail("Error: Same points");
return 1;
}
// Construction of the circle
GC_MakeCircle aCir =
GC_MakeCircle(aCartPointA->Pnt(), aCartPointB->Pnt(), aCartPointC->Pnt());
occ::handle<Geom_Circle> aGeomCircle;
try
{
aGeomCircle = aCir.Value();
}
catch (StdFail_NotDone const&)
{
Message::SendFail("Error: can't create circle");
return 1;
}
DisplayCircle(aGeomCircle, aName, isFilled, anUStart, anUEnd);
}
// Arguments: AIS_Plane AIS_Point Real
else if (aShapeA->Type() == AIS_KindOfInteractive_Datum && aShapeA->Signature() == 7)
{
occ::handle<AIS_Plane> anAISPlane = occ::down_cast<AIS_Plane>(aShapeA);
occ::handle<AIS_Point> anAISPointB = occ::down_cast<AIS_Point>(aShapeB);
if (anAISPointB.IsNull())
{
Message::SendFail("Error: 2d element is a expected to be a point");
return 1;
}
// Check that the radius is >= 0
const double anR = Draw::Atof(argv[4]);
if (anR <= 0)
{
Message::SendFail("Syntax error: the radius must be >=0");
return 1;
}
// Recover the normal to the plane
occ::handle<Geom_Plane> aGeomPlane = anAISPlane->Component();
occ::handle<Geom_Point> aGeomPointB = anAISPointB->Component();
occ::handle<Geom_CartesianPoint> aCartPointB =
occ::down_cast<Geom_CartesianPoint>(aGeomPointB);
gp_Pln aGpPlane = aGeomPlane->Pln();
gp_Ax1 aGpAxe = aGpPlane.Axis();
gp_Dir aDir = aGpAxe.Direction();
gp_Pnt aCenter = aCartPointB->Pnt();
GC_MakeCircle aCir = GC_MakeCircle(aCenter, aDir, anR);
occ::handle<Geom_Circle> aGeomCircle;
try
{
aGeomCircle = aCir.Value();
}
catch (StdFail_NotDone const&)
{
Message::SendFail("Error: can't create circle");
return 1;
}
DisplayCircle(aGeomCircle, aName, isFilled, anUStart, anUEnd);
}
else
{
Message::SendFail("Error: 1st argument has an unexpected type");
return 1;
}
}
else // No arguments: selection in the viewer
{
// Get the name of the circle
TCollection_AsciiString aName(argv[1]);
NCollection_List<TopoDS_Shape> aShapes;
ViewerTest::GetSelectedShapes(aShapes);
if (aShapes.Extent() != 3 && aShapes.Extent() != 2)
{
Message::SendFail("Error: Wrong number of selected shapes.");
return 1;
}
const TopoDS_Shape& aShapeA = aShapes.First();
if (aShapeA.ShapeType() == TopAbs_VERTEX)
{
if (aShapes.Extent() != 3)
{
Message::SendFail("Error: wrong number of selected shapes.");
return 1;
}
NCollection_List<TopoDS_Shape>::Iterator anIter(aShapes);
anIter.Next();
const TopoDS_Shape& aShapeB = anIter.Value();
anIter.Next();
const TopoDS_Shape& aShapeC = anIter.Value();
// Get isFilled
bool isFilled;
std::cout << "Enter filled status (0 or 1)\n";
std::cin >> isFilled;
// Construction of the circle
gp_Pnt A = BRep_Tool::Pnt(TopoDS::Vertex(aShapeA));
gp_Pnt B = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
gp_Pnt C = BRep_Tool::Pnt(TopoDS::Vertex(aShapeC));
GC_MakeCircle aCir = GC_MakeCircle(A, B, C);
occ::handle<Geom_Circle> aGeomCircle;
try
{
aGeomCircle = aCir.Value();
}
catch (StdFail_NotDone const&)
{
Message::SendFail("Error: can't create circle");
return 1;
}
DisplayCircle(aGeomCircle, aName, isFilled, anUStart, anUEnd);
}
else if (aShapeA.ShapeType() == TopAbs_FACE)
{
const TopoDS_Shape& aShapeB = aShapes.Last();
// Recover the radius
double aRad = 0.0;
do
{
std::cout << " Enter the value of the radius:\n";
std::cin >> aRad;
} while (aRad <= 0);
// Get filled status
bool isFilled;
std::cout << "Enter filled status (0 or 1)\n";
std::cin >> isFilled;
// Recover the normal to the plane. tag
TopoDS_Face aFace = TopoDS::Face(aShapeA);
BRepAdaptor_Surface aSurface(aFace, false);
gp_Pln aPlane = aSurface.Plane();
occ::handle<Geom_Plane> aGeomPlane = new Geom_Plane(aPlane);
gp_Pln aGpPlane = aGeomPlane->Pln();
gp_Ax1 aGpAxe = aGpPlane.Axis();
gp_Dir aDir = aGpAxe.Direction();
// Recover the center
gp_Pnt aCenter = BRep_Tool::Pnt(TopoDS::Vertex(aShapeB));
// Construct the circle
GC_MakeCircle aCir = GC_MakeCircle(aCenter, aDir, aRad);
occ::handle<Geom_Circle> aGeomCircle;
try
{
aGeomCircle = aCir.Value();
}
catch (StdFail_NotDone const&)
{
Message::SendFail("Error: can't create circle");
return 1;
}
DisplayCircle(aGeomCircle, aName, isFilled, anUStart, anUEnd);
}
else
{
Message::SendFail("Error: You should select face and vertex or three vertices.");
return 1;
}
}
return 0;
}
//=================================================================================================
static int VDrawText(Draw_Interpretor& theDI, int theArgsNb, const char** theArgVec)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (theArgsNb < 3)
{
Message::SendFail("Syntax error: wrong number of arguments. See usage:");
theDI.PrintHelp(theArgVec[0]);
return 1;
}
else if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
int anArgIt = 1;
TCollection_ExtendedString aName(theArgVec[anArgIt++], true);
TCollection_ExtendedString aText(theArgVec[anArgIt++], true);
occ::handle<AIS_TextLabel> aTextPrs;
ViewerTest_AutoUpdater anAutoUpdater(aContext, ViewerTest::CurrentView());
bool isNewPrs = false;
if (GetMapOfAIS().IsBound2(aName))
{
aTextPrs = occ::down_cast<AIS_TextLabel>(GetMapOfAIS().Find2(aName));
}
if (aTextPrs.IsNull())
{
isNewPrs = true;
aTextPrs = new AIS_TextLabel();
}
aTextPrs->SetText(aText);
occ::handle<Graphic3d_TransformPers> aTrsfPers;
Aspect_TypeOfDisplayText aDisplayType = Aspect_TODT_NORMAL;
bool aHasPlane = false;
gp_Dir aNormal;
gp_Dir aDirection;
gp_Pnt aPos;
occ::handle<Font_TextFormatter> aTextFormatter;
for (; anArgIt < theArgsNb; ++anArgIt)
{
TCollection_AsciiString aParam(theArgVec[anArgIt]);
aParam.LowerCase();
if (anAutoUpdater.parseRedrawMode(aParam))
{
continue;
}
else if ((aParam == "-pos" || aParam == "-position") && anArgIt + 3 < theArgsNb)
{
aPos.SetX(Draw::Atof(theArgVec[++anArgIt]));
aPos.SetY(Draw::Atof(theArgVec[++anArgIt]));
aPos.SetZ(Draw::Atof(theArgVec[++anArgIt]));
aTextPrs->SetPosition(aPos);
}
else if (aParam == "-color")
{
Quantity_Color aColor;
int aNbParsed = Draw::ParseColor(theArgsNb - anArgIt - 1, theArgVec + anArgIt + 1, aColor);
if (aNbParsed == 0)
{
Message::SendFail() << "Syntax error at '" << aParam << "'";
return 1;
}
anArgIt += aNbParsed;
aTextPrs->SetColor(aColor);
}
else if ((aParam == "-halign" || aParam == "-valign" || aParam == "-align")
&& anArgIt + 1 < theArgsNb)
{
TCollection_AsciiString aType(theArgVec[++anArgIt]);
aType.LowerCase();
if (aType == "left")
{
aTextPrs->SetHJustification(Graphic3d_HTA_LEFT);
if (aParam == "-valign")
{
Message::SendFail() << "Syntax error at '" << aParam << "'";
return 1;
}
}
else if (aType == "center")
{
if (aParam == "-halign" || aParam == "-align")
{
aTextPrs->SetHJustification(Graphic3d_HTA_CENTER);
}
if (aParam == "-valign" || aParam == "-align")
{
aTextPrs->SetVJustification(Graphic3d_VTA_CENTER);
}
}
else if (aType == "right")
{
aTextPrs->SetHJustification(Graphic3d_HTA_RIGHT);
if (aParam == "-valign")
{
Message::SendFail() << "Syntax error at '" << aParam << "'";
return 1;
}
}
else if (aType == "top")
{
aTextPrs->SetVJustification(Graphic3d_VTA_TOP);
if (aParam == "-halign")
{
Message::SendFail() << "Syntax error at '" << aParam << "'";
return 1;
}
}
else if (aType == "bottom")
{
aTextPrs->SetVJustification(Graphic3d_VTA_BOTTOM);
if (aParam == "-halign")
{
Message::SendFail() << "Syntax error at '" << aParam << "'";
return 1;
}
}
else if (aType == "topfirstline")
{
aTextPrs->SetVJustification(Graphic3d_VTA_TOPFIRSTLINE);
if (aParam == "-halign")
{
Message::SendFail() << "Syntax error at '" << aParam << "'";
return 1;
}
}
else
{
Message::SendFail() << "Syntax error at '" << aParam << "'";
return 1;
}
}
else if (aParam == "-angle" && anArgIt + 1 < theArgsNb)
{
aTextPrs->SetAngle(Draw::Atof(theArgVec[++anArgIt]) * (M_PI / 180.0));
}
else if (aParam == "-zoom" || aParam == "-nozoom" || aParam == "-zoomable"
|| aParam == "-nonzoomable")
{
const bool isZoomable = Draw::ParseOnOffNoIterator(theArgsNb, theArgVec, anArgIt);
aTextPrs->SetZoomable(isZoomable);
}
else if (aParam == "-height" && anArgIt + 1 < theArgsNb)
{
aTextPrs->SetHeight(Draw::Atof(theArgVec[++anArgIt]));
}
else if (aParam == "-wrapping" && anArgIt + 1 < theArgsNb)
{
if (aTextFormatter.IsNull())
{
aTextFormatter = new Font_TextFormatter();
}
aTextFormatter->SetWrapping((float)Draw::Atof(theArgVec[++anArgIt]));
}
else if (aParam == "-wordwrapping")
{
const bool isWordWrapping = Draw::ParseOnOffNoIterator(theArgsNb, theArgVec, anArgIt);
aTextFormatter->SetWordWrapping(isWordWrapping);
}
else if (aParam == "-aspect" && anArgIt + 1 < theArgsNb)
{
TCollection_AsciiString anOption(theArgVec[++anArgIt]);
anOption.LowerCase();
Font_FontAspect aFontAspect = Font_FA_Undefined;
if (!parseFontStyle(anOption, aFontAspect))
{
Message::SendFail() << "Syntax error: unknown font aspect '" << anOption << "'";
return 1;
}
aTextPrs->SetFontAspect(aFontAspect);
}
else if (aParam == "-font" && anArgIt + 1 < theArgsNb)
{
aTextPrs->SetFont(theArgVec[++anArgIt]);
}
else if (aParam == "-plane" && anArgIt + 6 < theArgsNb)
{
aNormal.SetCoord(Draw::Atof(theArgVec[anArgIt + 1]),
Draw::Atof(theArgVec[anArgIt + 2]),
Draw::Atof(theArgVec[anArgIt + 3]));
aDirection.SetCoord(Draw::Atof(theArgVec[anArgIt + 4]),
Draw::Atof(theArgVec[anArgIt + 5]),
Draw::Atof(theArgVec[anArgIt + 6]));
aHasPlane = true;
anArgIt += 6;
}
else if (aParam == "-flipping" || aParam == "-noflipping" || aParam == "-flip"
|| aParam == "-noflip")
{
const bool toFlip = Draw::ParseOnOffNoIterator(theArgsNb, theArgVec, anArgIt);
aTextPrs->SetFlipping(toFlip);
}
else if (aParam == "-ownanchor" || aParam == "-noownanchor")
{
const bool isOwnAnchor = Draw::ParseOnOffNoIterator(theArgsNb, theArgVec, anArgIt);
aTextPrs->SetOwnAnchorPoint(isOwnAnchor);
}
else if ((aParam == "-disptype" || aParam == "-displaytype") && anArgIt + 1 < theArgsNb)
{
TCollection_AsciiString aType(theArgVec[++anArgIt]);
aType.LowerCase();
if (aType == "subtitle")
{
aDisplayType = Aspect_TODT_SUBTITLE;
}
else if (aType == "decal")
{
aDisplayType = Aspect_TODT_DEKALE;
}
else if (aType == "blend")
{
aDisplayType = Aspect_TODT_BLEND;
}
else if (aType == "dimension")
{
aDisplayType = Aspect_TODT_DIMENSION;
}
else if (aType == "normal")
{
aDisplayType = Aspect_TODT_NORMAL;
}
else if (aType == "shadow")
{
aDisplayType = Aspect_TODT_SHADOW;
}
else
{
Message::SendFail() << "Syntax error: wrong display type '" << aType << "'";
return 1;
}
}
else if (aParam == "-subcolor" || aParam == "-subtitlecolor")
{
Quantity_Color aColor;
int aNbParsed = Draw::ParseColor(theArgsNb - anArgIt - 1, theArgVec + anArgIt + 1, aColor);
if (aNbParsed == 0)
{
Message::SendFail() << "Syntax error at '" << aParam << "'";
return 1;
}
anArgIt += aNbParsed;
aTextPrs->SetColorSubTitle(aColor);
}
else if (aParam == "-2d")
{
aTrsfPers = new Graphic3d_TransformPers(Graphic3d_TMF_2d);
}
else if (aParam == "-trsfperspos" || aParam == "-perspos")
{
if (anArgIt + 2 >= theArgsNb)
{
Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'.";
return 1;
}
TCollection_AsciiString aX(theArgVec[++anArgIt]);
TCollection_AsciiString aY(theArgVec[++anArgIt]);
TCollection_AsciiString aZ = "0";
if (!aX.IsIntegerValue() || !aY.IsIntegerValue())
{
Message::SendFail() << "Error: wrong syntax at '" << aParam << "'.";
return 1;
}
if (anArgIt + 1 < theArgsNb)
{
TCollection_AsciiString aTemp = theArgVec[anArgIt + 1];
if (aTemp.IsIntegerValue())
{
aZ = aTemp;
++anArgIt;
}
}
int aCorner = Aspect_TOTP_CENTER;
if (aX.IntegerValue() > 0.0)
{
aCorner |= Aspect_TOTP_RIGHT;
}
else if (aX.IntegerValue() < 0.0)
{
aCorner |= Aspect_TOTP_LEFT;
}
if (aY.IntegerValue() > 0.0)
{
aCorner |= Aspect_TOTP_TOP;
}
else if (aY.IntegerValue() < 0.0)
{
aCorner |= Aspect_TOTP_BOTTOM;
}
aTrsfPers = new Graphic3d_TransformPers(aTrsfPers->Mode(),
Aspect_TypeOfTriedronPosition(aCorner),
NCollection_Vec2<int>(aZ.IntegerValue()));
}
else
{
Message::SendFail() << "Syntax error: unknown argument '" << aParam << "'";
return 1;
}
}
aTextPrs->SetTextFormatter(aTextFormatter);
if (aHasPlane)
{
aTextPrs->SetOrientation3D(gp_Ax2(aPos, aNormal, aDirection));
}
aTextPrs->SetDisplayType(aDisplayType);
if (!aTrsfPers.IsNull())
{
aContext->SetTransformPersistence(aTextPrs, aTrsfPers);
aTextPrs->SetZLayer(Graphic3d_ZLayerId_TopOSD);
if (aTextPrs->Position().Z() != 0)
{
aTextPrs->SetPosition(gp_Pnt(aTextPrs->Position().X(), aTextPrs->Position().Y(), 0));
}
}
else if (!aTextPrs->TransformPersistence().IsNull())
{
aContext->SetTransformPersistence(aTextPrs, occ::handle<Graphic3d_TransformPers>());
}
if (isNewPrs)
{
ViewerTest::Display(aName, aTextPrs, false);
}
else
{
aContext->Redisplay(aTextPrs, false, true);
}
return 0;
}
#include <cmath>
#include <gp_Pnt.hxx>
#include <Graphic3d_ArrayOfPrimitives.hxx>
#include <Poly_Triangle.hxx>
#include <Poly_Triangulation.hxx>
#include <Standard_ShortReal.hxx>
#include <AIS_Triangulation.hxx>
#include <StdPrs_ToolTriangulatedShape.hxx>
#include <Poly_Connect.hxx>
#include <gp_Dir.hxx>
#include <Graphic3d_GraphicDriver.hxx>
#include <Prs3d_ShadingAspect.hxx>
#include <Graphic3d_MaterialAspect.hxx>
#include <Graphic3d_AspectFillArea3d.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <utility>
class AIS_InteractiveObject;
//=================================================================================================
occ::handle<Poly_Triangulation> CalculationOfSphere(double X,
double Y,
double Z,
int res,
double Radius)
{
double mRadius = Radius;
double mCenter[3] = {X, Y, Z};
int mThetaResolution;
int mPhiResolution;
double mStartTheta = 0; // StartTheta;
double mEndTheta = 360; // EndTheta;
double mStartPhi = 0; // StartPhi;
double mEndPhi = 180; // EndPhi;
res = res < 4 ? 4 : res;
mThetaResolution = res;
mPhiResolution = res;
int i, j;
int jStart, jEnd, numOffset;
double x[3], n[3], deltaPhi, deltaTheta, phi, theta, radius;
double startTheta, endTheta, startPhi, endPhi;
int base, numPoles = 0, thetaResolution, phiResolution;
int pts[3];
int piece = -1;
int numPieces = 1;
if (numPieces > mThetaResolution)
{
numPieces = mThetaResolution;
}
int localThetaResolution = mThetaResolution;
double localStartTheta = mStartTheta;
double localEndTheta = mEndTheta;
while (localEndTheta < localStartTheta)
{
localEndTheta += 360.0;
}
deltaTheta = (localEndTheta - localStartTheta) / localThetaResolution;
// Change the ivars based on pieces.
int start, end;
start = piece * localThetaResolution / numPieces;
end = (piece + 1) * localThetaResolution / numPieces;
localEndTheta = localStartTheta + (double)(end)*deltaTheta;
localStartTheta = localStartTheta + (double)(start)*deltaTheta;
localThetaResolution = end - start;
// Create north pole if needed
int number_point = 0;
int number_pointArray = 0;
if (mStartPhi <= 0.0)
{
number_pointArray++;
numPoles++;
}
if (mEndPhi >= 180.0)
{
number_pointArray++;
numPoles++;
}
// Check data, determine increments, and convert to radians
startTheta = (localStartTheta < localEndTheta ? localStartTheta : localEndTheta);
startTheta *= M_PI / 180.0;
endTheta = (localEndTheta > localStartTheta ? localEndTheta : localStartTheta);
endTheta *= M_PI / 180.0;
startPhi = (mStartPhi < mEndPhi ? mStartPhi : mEndPhi);
startPhi *= M_PI / 180.0;
endPhi = (mEndPhi > mStartPhi ? mEndPhi : mStartPhi);
endPhi *= M_PI / 180.0;
phiResolution = mPhiResolution - numPoles;
deltaPhi = (endPhi - startPhi) / (mPhiResolution - 1);
thetaResolution = localThetaResolution;
if (fabs(localStartTheta - localEndTheta) < 360.0)
{
++localThetaResolution;
}
deltaTheta = (endTheta - startTheta) / thetaResolution;
jStart = (mStartPhi <= 0.0 ? 1 : 0);
jEnd = (mEndPhi >= 180.0 ? mPhiResolution - 1 : mPhiResolution);
// Create intermediate points
for (i = 0; i < localThetaResolution; i++)
{
for (j = jStart; j < jEnd; j++)
{
number_pointArray++;
}
}
// Generate mesh connectivity
base = phiResolution * localThetaResolution;
int number_triangle = 0;
if (mStartPhi <= 0.0)
{ // around north pole
number_triangle += localThetaResolution;
}
if (mEndPhi >= 180.0)
{ // around south pole
number_triangle += localThetaResolution;
}
// bands in-between poles
for (i = 0; i < localThetaResolution; i++)
{
for (j = 0; j < (phiResolution - 1); j++)
{
number_triangle += 2;
}
}
occ::handle<Poly_Triangulation> polyTriangulation =
new Poly_Triangulation(number_pointArray, number_triangle, false, true);
if (mStartPhi <= 0.0)
{
x[0] = mCenter[0];
x[1] = mCenter[1];
x[2] = mCenter[2] + mRadius;
polyTriangulation->SetNode(1, gp_Pnt(x[0], x[1], x[2]));
}
// Create south pole if needed
if (mEndPhi >= 180.0)
{
x[0] = mCenter[0];
x[1] = mCenter[1];
x[2] = mCenter[2] - mRadius;
polyTriangulation->SetNode(2, gp_Pnt(x[0], x[1], x[2]));
}
number_point = 3;
for (i = 0; i < localThetaResolution; i++)
{
theta = localStartTheta * M_PI / 180.0 + i * deltaTheta;
for (j = jStart; j < jEnd; j++)
{
phi = startPhi + j * deltaPhi;
radius = mRadius * sin((double)phi);
n[0] = radius * cos((double)theta);
n[1] = radius * sin((double)theta);
n[2] = mRadius * cos((double)phi);
x[0] = n[0] + mCenter[0];
x[1] = n[1] + mCenter[1];
x[2] = n[2] + mCenter[2];
polyTriangulation->SetNode(number_point, gp_Pnt(x[0], x[1], x[2]));
number_point++;
}
}
numPoles = 3;
number_triangle = 1;
if (mStartPhi <= 0.0)
{ // around north pole
for (i = 0; i < localThetaResolution; i++)
{
pts[0] = phiResolution * i + numPoles;
pts[1] = (phiResolution * (i + 1) % base) + numPoles;
pts[2] = 1;
polyTriangulation->SetTriangle(number_triangle, Poly_Triangle(pts[0], pts[1], pts[2]));
number_triangle++;
}
}
if (mEndPhi >= 180.0)
{ // around south pole
numOffset = phiResolution - 1 + numPoles;
for (i = 0; i < localThetaResolution; i++)
{
pts[0] = phiResolution * i + numOffset;
pts[2] = ((phiResolution * (i + 1)) % base) + numOffset;
pts[1] = numPoles - 1;
polyTriangulation->SetTriangle(number_triangle, Poly_Triangle(pts[0], pts[1], pts[2]));
number_triangle++;
}
}
// bands in-between poles
for (i = 0; i < localThetaResolution; i++)
{
for (j = 0; j < (phiResolution - 1); j++)
{
pts[0] = phiResolution * i + j + numPoles;
pts[1] = pts[0] + 1;
pts[2] = ((phiResolution * (i + 1) + j) % base) + numPoles + 1;
polyTriangulation->SetTriangle(number_triangle, Poly_Triangle(pts[0], pts[1], pts[2]));
number_triangle++;
pts[1] = pts[2];
pts[2] = pts[1] - 1;
polyTriangulation->SetTriangle(number_triangle, Poly_Triangle(pts[0], pts[1], pts[2]));
number_triangle++;
}
}
Poly_Connect pc(polyTriangulation);
int index[3];
constexpr double Tol = Precision::Confusion();
gp_Dir Nor;
for (i = 1; i <= polyTriangulation->NbNodes(); i++)
{
gp_XYZ eqPlan(0, 0, 0);
for (pc.Initialize(i); pc.More(); pc.Next())
{
polyTriangulation->Triangle(pc.Value()).Get(index[0], index[1], index[2]);
gp_XYZ v1(polyTriangulation->Node(index[1]).Coord()
- polyTriangulation->Node(index[0]).Coord());
gp_XYZ v2(polyTriangulation->Node(index[2]).Coord()
- polyTriangulation->Node(index[1]).Coord());
gp_XYZ vv = v1 ^ v2;
double mod = vv.Modulus();
if (mod < Tol)
{
continue;
}
eqPlan += vv / mod;
}
double modmax = eqPlan.Modulus();
if (modmax > Tol)
{
Nor = gp_Dir(eqPlan);
}
else
{
Nor = gp_Dir(gp_Dir::D::Z);
}
polyTriangulation->SetNormal(i, Nor.XYZ());
}
return polyTriangulation;
}
//=================================================================================================
static int VDrawSphere(Draw_Interpretor& /*di*/, int argc, const char** argv)
{
// check for errors
occ::handle<AIS_InteractiveContext> aContextAIS = ViewerTest::GetAISContext();
if (aContextAIS.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
else if (argc < 3)
{
Message::SendFail() << "Syntax error: wrong number of arguments.\n"
<< "Use: " << argv[0]
<< " shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0]";
return 1;
}
// read the arguments
TCollection_AsciiString aShapeName(argv[1]);
int aResolution = Draw::Atoi(argv[2]);
double aCenterX = (argc > 5) ? Draw::Atof(argv[3]) : 0.0;
double aCenterY = (argc > 5) ? Draw::Atof(argv[4]) : 0.0;
double aCenterZ = (argc > 5) ? Draw::Atof(argv[5]) : 0.0;
double aRadius = (argc > 6) ? Draw::Atof(argv[6]) : 100.0;
bool toShowEdges = (argc > 7) ? Draw::Atoi(argv[7]) == 1 : false;
bool toPrintInfo = (argc > 8) ? Draw::Atoi(argv[8]) == 1 : true;
// remove AIS object with given name from map
VDisplayAISObject(aShapeName, occ::handle<AIS_InteractiveObject>());
if (toPrintInfo)
{
std::cout << "Compute Triangulation...\n";
}
occ::handle<AIS_Triangulation> aShape =
new AIS_Triangulation(CalculationOfSphere(aCenterX, aCenterY, aCenterZ, aResolution, aRadius));
const int aNumberPoints = aShape->GetTriangulation()->NbNodes();
const int aNumberTriangles = aShape->GetTriangulation()->NbTriangles();
// stupid initialization of Green color in RGBA space as integer
// probably wrong for big-endian CPUs
const NCollection_Vec4<uint8_t> aColor(0, 255, 0, 0);
// setup colors array per vertex
occ::handle<NCollection_HArray1<int>> aColorArray =
new NCollection_HArray1<int>(1, aNumberPoints);
for (int aNodeId = 1; aNodeId <= aNumberPoints; ++aNodeId)
{
aColorArray->SetValue(aNodeId, *reinterpret_cast<const int*>(aColor.GetData()));
}
aShape->SetColors(aColorArray);
// show statistics
int aPointsSize = aNumberPoints * 3 * sizeof(float); // 3x GLfloat
int aNormalsSize = aNumberPoints * 3 * sizeof(float); // 3x GLfloat
// clang-format off
int aColorsSize = aNumberPoints * 3 * sizeof(float); // 3x GLfloat without alpha
// clang-format on
int aTrianglesSize = aNumberTriangles * 3 * sizeof(int); // 3x GLint
int aPolyConnectSize = aNumberPoints * 4 + aNumberTriangles * 6 * 4;
int aTotalSize = aPointsSize + aNormalsSize + aColorsSize + aTrianglesSize;
aTotalSize >>= 20; // MB
aNormalsSize >>= 20;
aColorsSize >>= 20;
aTrianglesSize >>= 20;
aPolyConnectSize >>= 20;
if (toPrintInfo)
{
std::cout << "NumberOfPoints: " << aNumberPoints << "\n"
<< "NumberOfTriangles: " << aNumberTriangles << "\n"
<< "Amount of memory required for PolyTriangulation without Normals: "
<< (aTotalSize - aNormalsSize) << " Mb\n"
<< "Amount of memory for colors: " << aColorsSize << " Mb\n"
<< "Amount of memory for PolyConnect: " << aPolyConnectSize << " Mb\n"
<< "Amount of graphic card memory required: " << aTotalSize << " Mb\n";
}
// Setting material properties, very important for desirable visual result!
Graphic3d_MaterialAspect aMat(Graphic3d_NameOfMaterial_Plastified);
aMat.SetAmbientColor(Quantity_Color(NCollection_Vec3<float>(0.04f)));
aMat.SetSpecularColor(Quantity_Color(NCollection_Vec3<float>(0.50f)));
occ::handle<Graphic3d_AspectFillArea3d> anAspect =
new Graphic3d_AspectFillArea3d(Aspect_IS_SOLID,
Quantity_NOC_WHITE,
Quantity_NOC_YELLOW,
Aspect_TOL_SOLID,
1.0,
aMat,
aMat);
occ::handle<Prs3d_ShadingAspect> aShAsp = new Prs3d_ShadingAspect();
anAspect->SetDrawEdges(toShowEdges);
aShAsp->SetAspect(anAspect);
aShape->Attributes()->SetShadingAspect(aShAsp);
VDisplayAISObject(aShapeName, aShape);
return 0;
}
//=================================================================================================
static int VComputeHLR(Draw_Interpretor&, int theArgNb, const char** theArgVec)
{
TCollection_AsciiString aShapeName, aHlrName;
TopoDS_Shape aSh;
gp_Pnt anEye;
gp_Dir aDir;
gp_Ax2 aProjAx;
bool hasViewDirArg = false;
Prs3d_TypeOfHLR anAlgoType = Prs3d_TOH_PolyAlgo;
bool toShowCNEdges = false, toShowHiddenEdges = false;
int aNbIsolines = 0;
if (occ::handle<V3d_Viewer> aViewer = ViewerTest::GetViewerFromContext())
{
gp_Dir aRight;
occ::handle<V3d_View> aView = ViewerTest::CurrentView();
int aWidth, aHeight;
double aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ;
double aRightX, aRightY, aRightZ;
aView->Window()->Size(aWidth, aHeight);
aView->ConvertWithProj(aWidth, aHeight / 2, aRightX, aRightY, aRightZ, aDirX, aDirY, aDirZ);
aView->ConvertWithProj(aWidth / 2, aHeight / 2, aCentX, aCentY, aCentZ, aDirX, aDirY, aDirZ);
anEye.SetCoord(-aCentX, -aCentY, -aCentZ);
aDir.SetCoord(-aDirX, -aDirY, -aDirZ);
aRight.SetCoord(aRightX - aCentX, aRightY - aCentY, aRightZ - aCentZ);
aProjAx.SetLocation(anEye);
aProjAx.SetDirection(aDir);
aProjAx.SetXDirection(aRight);
}
for (int anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
TCollection_AsciiString anArgCase(theArgVec[anArgIter]);
anArgCase.LowerCase();
if (anArgIter + 1 < theArgNb
&& (anArgCase == "-algotype" || anArgCase == "-algo" || anArgCase == "-type"))
{
TCollection_AsciiString anArgNext(theArgVec[++anArgIter]);
anArgNext.LowerCase();
if (anArgNext == "polyalgo")
{
anAlgoType = Prs3d_TOH_PolyAlgo;
}
else if (anArgNext == "algo")
{
anAlgoType = Prs3d_TOH_Algo;
}
else
{
Message::SendFail() << "Syntax error: unknown algo type '" << anArgNext << "'";
return 1;
}
}
else if (anArgCase == "-showhiddenedges" || anArgCase == "-hiddenedges"
|| anArgCase == "-hidden")
{
toShowHiddenEdges = true;
if (anArgIter + 1 < theArgNb && Draw::ParseOnOff(theArgVec[anArgIter + 1], toShowHiddenEdges))
{
++anArgIter;
}
}
else if (anArgCase == "-showtangentedges" || anArgCase == "-tangentedges"
|| anArgCase == "-tangent")
{
toShowCNEdges = true;
if (anArgIter + 1 < theArgNb && Draw::ParseOnOff(theArgVec[anArgIter + 1], toShowCNEdges))
{
++anArgIter;
}
}
else if (anArgIter + 1 < theArgNb && (anArgCase == "-nbiso" || anArgCase == "-nbisolines"))
{
aNbIsolines = Draw::Atoi(theArgVec[++anArgIter]);
}
else if (aSh.IsNull())
{
aSh = DBRep::Get(theArgVec[anArgIter]);
aShapeName = theArgVec[anArgIter];
if (aSh.IsNull())
{
BRep_Builder aBrepBuilder;
BRepTools::Read(aSh, theArgVec[anArgIter], aBrepBuilder);
if (aSh.IsNull())
{
Message::SendFail() << "Syntax error: no shape with name " << theArgVec[anArgIter]
<< " found";
return 1;
}
}
}
else if (aHlrName.IsEmpty())
{
aHlrName = theArgVec[anArgIter];
}
else if (!hasViewDirArg && anArgIter + 8 < theArgNb)
{
hasViewDirArg = true;
gp_Dir anUp;
anEye.SetCoord(Draw::Atof(theArgVec[anArgIter + 0]),
Draw::Atof(theArgVec[anArgIter + 1]),
Draw::Atof(theArgVec[anArgIter + 2]));
aDir.SetCoord(Draw::Atof(theArgVec[anArgIter + 3]),
Draw::Atof(theArgVec[anArgIter + 4]),
Draw::Atof(theArgVec[anArgIter + 5]));
anUp.SetCoord(Draw::Atof(theArgVec[anArgIter + 6]),
Draw::Atof(theArgVec[anArgIter + 7]),
Draw::Atof(theArgVec[anArgIter + 8]));
aProjAx.SetLocation(anEye);
aProjAx.SetDirection(aDir);
aProjAx.SetYDirection(anUp);
anArgIter += 8;
}
else
{
Message::SendFail() << "Syntax error: unknown argument '" << theArgVec[anArgIter] << "'";
return 1;
}
}
if (aHlrName.IsEmpty() || aSh.IsNull()
|| (ViewerTest::GetAISContext().IsNull() && !hasViewDirArg))
{
Message::SendFail("Syntax error: wrong number of arguments");
return 1;
}
HLRAlgo_Projector aProjector(aProjAx);
TopoDS_Shape aVisible[6];
TopoDS_Shape aHidden[6];
if (anAlgoType == Prs3d_TOH_PolyAlgo)
{
occ::handle<HLRBRep_PolyAlgo> aPolyAlgo = new HLRBRep_PolyAlgo();
aPolyAlgo->Projector(aProjector);
aPolyAlgo->Load(aSh);
aPolyAlgo->Update();
HLRBRep_PolyHLRToShape aHLRToShape;
aHLRToShape.Update(aPolyAlgo);
aVisible[HLRBRep_Sharp] = aHLRToShape.VCompound();
aVisible[HLRBRep_OutLine] = aHLRToShape.OutLineVCompound(); // extract visible outlines
aVisible[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineVCompound();
if (toShowCNEdges)
{
aVisible[HLRBRep_RgNLine] = aHLRToShape.RgNLineVCompound();
}
if (toShowHiddenEdges)
{
aHidden[HLRBRep_Sharp] = aHLRToShape.HCompound();
aHidden[HLRBRep_OutLine] = aHLRToShape.OutLineHCompound();
aHidden[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineHCompound();
if (toShowCNEdges)
{
aHidden[HLRBRep_RgNLine] = aHLRToShape.RgNLineHCompound();
}
}
}
else
{
occ::handle<HLRBRep_Algo> aHlrAlgo = new HLRBRep_Algo();
aHlrAlgo->Add(aSh, aNbIsolines);
aHlrAlgo->Projector(aProjector);
aHlrAlgo->Update();
aHlrAlgo->Hide();
HLRBRep_HLRToShape aHLRToShape(aHlrAlgo);
aVisible[HLRBRep_Sharp] = aHLRToShape.VCompound();
aVisible[HLRBRep_OutLine] = aHLRToShape.OutLineVCompound();
aVisible[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineVCompound();
if (toShowCNEdges)
{
aVisible[HLRBRep_RgNLine] = aHLRToShape.RgNLineVCompound();
}
aVisible[HLRBRep_IsoLine] = aHLRToShape.IsoLineVCompound();
if (toShowHiddenEdges)
{
aHidden[HLRBRep_Sharp] = aHLRToShape.HCompound();
aHidden[HLRBRep_OutLine] = aHLRToShape.OutLineHCompound();
aHidden[HLRBRep_Rg1Line] = aHLRToShape.Rg1LineHCompound();
if (toShowCNEdges)
{
aHidden[HLRBRep_RgNLine] = aHLRToShape.RgNLineHCompound();
}
aHidden[HLRBRep_IsoLine] = aHLRToShape.IsoLineHCompound();
}
// extract 3d
// aVisible[HLRBRep_Sharp] = aHLRToShape.CompoundOfEdges (HLRBRep_Sharp, true,
// true); aVisible[HLRBRep_OutLine] = aHLRToShape.OutLineVCompound3d();
}
TopoDS_Compound aCompRes, aCompVis, aCompHid;
BRep_Builder aBuilder;
aBuilder.MakeCompound(aCompVis);
aBuilder.MakeCompound(aCompHid);
aBuilder.MakeCompound(aCompRes);
for (int aTypeIter = 0; aTypeIter < 6; ++aTypeIter)
{
if (!aVisible[aTypeIter].IsNull())
{
aBuilder.Add(aCompVis, aVisible[aTypeIter]);
}
if (!aHidden[aTypeIter].IsNull())
{
aBuilder.Add(aCompHid, aHidden[aTypeIter]);
}
}
aBuilder.Add(aCompRes, aCompVis);
aBuilder.Add(aCompRes, aCompHid);
// create an AIS shape and display it
if (!ViewerTest::GetAISContext().IsNull())
{
occ::handle<AIS_ColoredShape> anObject = new AIS_ColoredShape(aCompRes);
if (toShowHiddenEdges)
{
occ::handle<Prs3d_LineAspect> aLineAspect =
new Prs3d_LineAspect(Quantity_Color(Quantity_NOC_RED), Aspect_TOL_DASH, 1.0f);
for (int aTypeIter = 0; aTypeIter < 6; ++aTypeIter)
{
if (!aHidden[aTypeIter].IsNull())
{
occ::handle<AIS_ColoredDrawer> aDrawer = anObject->CustomAspects(aHidden[aTypeIter]);
aDrawer->SetLineAspect(aLineAspect);
aDrawer->SetWireAspect(aLineAspect);
aDrawer->SetFreeBoundaryAspect(aLineAspect);
aDrawer->SetUnFreeBoundaryAspect(aLineAspect);
}
}
}
ViewerTest::Display(aHlrName, anObject, true);
}
DBRep::Set(aHlrName.ToCString(), aCompRes);
return 0;
}
// This class is a wrap for Graphic3d_ArrayOfPrimitives; it is used for
// manipulating and displaying such an array with AIS context
class MyPArrayObject : public AIS_InteractiveObject
{
public:
MyPArrayObject(const occ::handle<Graphic3d_ArrayOfPrimitives>& thePArray)
: myPArray(thePArray)
{
}
MyPArrayObject(Graphic3d_TypeOfPrimitiveArray thePrimType,
const occ::handle<NCollection_HArray1<TCollection_AsciiString>>& theDesc,
const occ::handle<Graphic3d_AspectMarker3d>& theMarkerAspect)
{
Init(thePrimType, theDesc, theMarkerAspect, false);
}
//! Initialize the array from specified description.
bool Init(Graphic3d_TypeOfPrimitiveArray thePrimType,
const occ::handle<NCollection_HArray1<TCollection_AsciiString>>& theDesc,
const occ::handle<Graphic3d_AspectMarker3d>& theMarkerAspect,
bool theToPatch);
DEFINE_STANDARD_RTTI_INLINE(MyPArrayObject, AIS_InteractiveObject);
bool AcceptDisplayMode(const int theMode) const override { return theMode == 0; }
//! Sets color to this interactive object
//! @param theColor the color to be set
void SetColor(const Quantity_Color& theColor) override;
private:
void Compute(const occ::handle<PrsMgr_PresentationManager>& thePrsMgr,
const occ::handle<Prs3d_Presentation>& thePrs,
const int theMode) override;
void ComputeSelection(const occ::handle<SelectMgr_Selection>& theSel, const int theMode) override;
bool CheckInputCommand(
const TCollection_AsciiString& theCommand,
const occ::handle<NCollection_HArray1<TCollection_AsciiString>>& theArgsArray,
int& theArgIndex,
int theArgCount,
int theMaxArgs);
//! Sets color for the shading aspect of the drawer used in this interactive object
//! @param theColor the color to be set
void setColorForShadingAspect(const Quantity_Color& theColor);
//! Replaces shading aspect from myDrawer->Link() with the own shading aspect of myDrawer for this
//! interactive object
void replaceShadingAspect();
protected:
occ::handle<Graphic3d_AspectMarker3d> myMarkerAspect;
occ::handle<Graphic3d_ArrayOfPrimitives> myPArray;
};
void MyPArrayObject::Compute(const occ::handle<PrsMgr_PresentationManager>&,
const occ::handle<Prs3d_Presentation>& thePrs,
const int theMode)
{
if (myPArray.IsNull() || theMode != 0)
{
return;
}
occ::handle<Graphic3d_Group> aGroup = thePrs->NewGroup();
if (!myMarkerAspect.IsNull())
{
aGroup->SetGroupPrimitivesAspect(myMarkerAspect);
}
else
{
aGroup->SetGroupPrimitivesAspect(myDrawer->ShadingAspect()->Aspect());
}
aGroup->AddPrimitiveArray(myPArray);
}
bool MyPArrayObject::Init(Graphic3d_TypeOfPrimitiveArray thePrimType,
const occ::handle<NCollection_HArray1<TCollection_AsciiString>>& theDesc,
const occ::handle<Graphic3d_AspectMarker3d>& theMarkerAspect,
bool theToPatch)
{
myMarkerAspect = theMarkerAspect;
if (!theToPatch)
{
myPArray.Nullify();
}
// Parsing array description
int aVertexNum = 0, aBoundNum = 0, aEdgeNum = 0;
Graphic3d_ArrayFlags anArrayFlags = Graphic3d_ArrayFlags_None;
const int anArgsCount = theDesc->Length();
TCollection_AsciiString aCommand;
for (int anArgIndex = theDesc->Lower(); anArgIndex <= theDesc->Upper();)
{
aCommand = theDesc->Value(anArgIndex);
aCommand.LowerCase();
if (CheckInputCommand("-deinterleaved", theDesc, anArgIndex, 0, anArgsCount))
{
anArrayFlags |= Graphic3d_ArrayFlags_AttribsDeinterleaved;
}
else if (CheckInputCommand("-mutable", theDesc, anArgIndex, 0, anArgsCount))
{
anArrayFlags |= Graphic3d_ArrayFlags_AttribsMutable;
anArrayFlags |= Graphic3d_ArrayFlags_IndexesMutable;
}
// vertex command
else if (CheckInputCommand("v", theDesc, anArgIndex, 3, anArgsCount))
{
// vertex has a normal or normal with color or texel
if (CheckInputCommand("n", theDesc, anArgIndex, 3, anArgsCount))
{
anArrayFlags = anArrayFlags | Graphic3d_ArrayFlags_VertexNormal;
}
// vertex has a color
if (CheckInputCommand("c", theDesc, anArgIndex, 3, anArgsCount))
{
anArrayFlags = anArrayFlags | Graphic3d_ArrayFlags_VertexColor;
}
// vertex has a texel
if (CheckInputCommand("t", theDesc, anArgIndex, 2, anArgsCount))
{
anArrayFlags = anArrayFlags | Graphic3d_ArrayFlags_VertexTexel;
}
aVertexNum++;
}
// bound command
else if (CheckInputCommand("b", theDesc, anArgIndex, 1, anArgsCount))
{
// bound has color
if (CheckInputCommand("c", theDesc, anArgIndex, 3, anArgsCount))
{
anArrayFlags = anArrayFlags | Graphic3d_ArrayFlags_BoundColor;
}
aBoundNum++;
}
// edge command
else if (CheckInputCommand("e", theDesc, anArgIndex, 1, anArgsCount))
{
aEdgeNum++;
}
// unknown command
else
{
anArgIndex++;
}
}
if (myPArray.IsNull())
{
myPArray = Graphic3d_ArrayOfPrimitives::CreateArray(thePrimType,
aVertexNum,
aBoundNum,
aEdgeNum,
anArrayFlags);
if (myPArray->HasVertexColors())
{
myDrawer->SetupOwnShadingAspect();
Graphic3d_MaterialAspect aMat(Graphic3d_NameOfMaterial_Plastified);
aMat.SetSpecularColor(Quantity_NOC_BLACK);
aMat.SetEmissiveColor(Quantity_NOC_BLACK);
aMat.SetAmbientColor(Quantity_Color(NCollection_Vec3<float>(0.5f)));
aMat.SetDiffuseColor(Quantity_Color(NCollection_Vec3<float>(0.5f)));
myDrawer->ShadingAspect()->SetMaterial(aMat);
myDrawer->ShadingAspect()->SetColor(Quantity_NOC_WHITE);
}
}
else
{
if (myPArray->Type() != thePrimType || aVertexNum > myPArray->VertexNumberAllocated()
|| aEdgeNum > myPArray->EdgeNumberAllocated()
|| aBoundNum > myPArray->BoundNumberAllocated() || !myPArray->Attributes()->IsMutable()
|| (!myPArray->Indices().IsNull() && !myPArray->Indices()->IsMutable()))
{
Message::SendFail("Syntax error: array cannot be patched");
return false;
}
myPArray->Attributes()->NbElements = aVertexNum;
if (occ::handle<Graphic3d_AttribBuffer> anAttribs =
occ::down_cast<Graphic3d_AttribBuffer>(myPArray->Attributes()))
{
anAttribs->Invalidate(0, aVertexNum - 1);
}
if (!myPArray->Indices().IsNull())
{
myPArray->Indices()->NbElements = aEdgeNum;
}
if (!myPArray->Bounds().IsNull())
{
myPArray->Bounds()->NbBounds = aBoundNum;
}
}
int aVertIndex = 0;
for (int anArgIndex = theDesc->Lower(); anArgIndex <= theDesc->Upper();)
{
aCommand = theDesc->Value(anArgIndex);
aCommand.LowerCase();
if (!aCommand.IsAscii() || aCommand.IsEmpty())
{
break;
}
// skip beautifiers (syntax is not actually validated)
if (aCommand == "-deinterleaved" || aCommand == "-mutable" || aCommand.Value(1) == '('
|| aCommand.Value(1) == ')' || aCommand.Value(1) == ',')
{
++anArgIndex;
}
// vertex command
else if (CheckInputCommand("v", theDesc, anArgIndex, 3, anArgsCount))
{
const NCollection_Vec3<float> aVert((float)theDesc->Value(anArgIndex - 3).RealValue(),
(float)theDesc->Value(anArgIndex - 2).RealValue(),
(float)theDesc->Value(anArgIndex - 1).RealValue());
if ((anArrayFlags & Graphic3d_ArrayFlags_AttribsDeinterleaved) != 0
|| (anArrayFlags & Graphic3d_ArrayFlags_AttribsMutable) != 0)
{
++aVertIndex;
myPArray->SetVertice(aVertIndex, aVert.x(), aVert.y(), aVert.z());
}
else
{
aVertIndex = myPArray->AddVertex(aVert);
}
// vertex has a normal or normal with color or texel
if (CheckInputCommand("n", theDesc, anArgIndex, 3, anArgsCount))
{
const NCollection_Vec3<float> aNorm((float)theDesc->Value(anArgIndex - 3).RealValue(),
(float)theDesc->Value(anArgIndex - 2).RealValue(),
(float)theDesc->Value(anArgIndex - 1).RealValue());
myPArray->SetVertexNormal(aVertIndex, aNorm.x(), aNorm.y(), aNorm.z());
}
if (CheckInputCommand("c", theDesc, anArgIndex, 3, anArgsCount))
{
const NCollection_Vec3<double> aCol(theDesc->Value(anArgIndex - 3).RealValue(),
theDesc->Value(anArgIndex - 2).RealValue(),
theDesc->Value(anArgIndex - 1).RealValue());
myPArray->SetVertexColor(aVertIndex, aCol.r(), aCol.g(), aCol.b());
}
if (CheckInputCommand("t", theDesc, anArgIndex, 2, anArgsCount))
{
const NCollection_Vec2<float> aTex((float)theDesc->Value(anArgIndex - 2).RealValue(),
(float)theDesc->Value(anArgIndex - 1).RealValue());
myPArray->SetVertexTexel(aVertIndex, aTex.x(), aTex.y());
}
}
// bounds command
else if (CheckInputCommand("b", theDesc, anArgIndex, 1, anArgsCount))
{
int aVertCount = theDesc->Value(anArgIndex - 1).IntegerValue();
if (CheckInputCommand("c", theDesc, anArgIndex, 3, anArgsCount))
{
myPArray->AddBound(aVertCount,
theDesc->Value(anArgIndex - 3).RealValue(),
theDesc->Value(anArgIndex - 2).RealValue(),
theDesc->Value(anArgIndex - 1).RealValue());
}
else
{
myPArray->AddBound(aVertCount);
}
}
// edge command
else if (CheckInputCommand("e", theDesc, anArgIndex, 1, anArgsCount))
{
const int anEdge = theDesc->Value(anArgIndex - 1).IntegerValue();
myPArray->AddEdge(anEdge);
}
// unknown command
else
{
Message::SendFail() << "Syntax error: unknown argument '" << theDesc->Value(anArgIndex)
<< "'";
return false;
}
}
return true;
}
//=================================================================================================
void MyPArrayObject::SetColor(const Quantity_Color& theColor)
{
AIS_InteractiveObject::SetColor(theColor);
setColorForShadingAspect(theColor);
if (myMarkerAspect)
{
myMarkerAspect->SetColor(theColor);
}
SynchronizeAspects();
}
void MyPArrayObject::ComputeSelection(const occ::handle<SelectMgr_Selection>& theSelection,
const int theMode)
{
if (theMode != 0 || myPArray.IsNull())
{
return;
}
occ::handle<SelectMgr_EntityOwner> anOwner = new SelectMgr_EntityOwner(this);
if (occ::handle<Graphic3d_ArrayOfTriangles> aTris =
occ::down_cast<Graphic3d_ArrayOfTriangles>(myPArray))
{
occ::handle<Select3D_SensitivePrimitiveArray> aSensitive =
new Select3D_SensitivePrimitiveArray(anOwner);
aSensitive->InitTriangulation(myPArray->Attributes(),
myPArray->Indices(),
TopLoc_Location(),
true);
theSelection->Add(aSensitive);
}
else if (occ::handle<Graphic3d_ArrayOfSegments> aSegs =
occ::down_cast<Graphic3d_ArrayOfSegments>(myPArray))
{
if (aSegs->EdgeNumber() > 0)
{
for (int aPntIter = 1; aPntIter <= aSegs->EdgeNumber(); aPntIter += 2)
{
occ::handle<Select3D_SensitiveSegment> aSeg =
new Select3D_SensitiveSegment(anOwner,
aSegs->Vertice(aSegs->Edge(aPntIter)),
aSegs->Vertice(aSegs->Edge(aPntIter + 1)));
aSeg->SetSensitivityFactor(4);
theSelection->Add(aSeg);
}
}
else
{
for (int aPntIter = 1; aPntIter <= aSegs->VertexNumber(); aPntIter += 2)
{
occ::handle<Select3D_SensitiveSegment> aSeg =
new Select3D_SensitiveSegment(anOwner,
aSegs->Vertice(aPntIter),
aSegs->Vertice(aPntIter + 1));
aSeg->SetSensitivityFactor(4);
theSelection->Add(aSeg);
}
}
}
else
{
occ::handle<Select3D_SensitivePrimitiveArray> aSensitive =
new Select3D_SensitivePrimitiveArray(anOwner);
aSensitive->SetSensitivityFactor(8);
aSensitive->InitPoints(myPArray->Attributes(), myPArray->Indices(), TopLoc_Location(), true);
theSelection->Add(aSensitive);
}
}
bool MyPArrayObject::CheckInputCommand(
const TCollection_AsciiString& theCommand,
const occ::handle<NCollection_HArray1<TCollection_AsciiString>>& theArgsArray,
int& theArgIndex,
int theArgCount,
int theMaxArgs)
{
// check if there is more elements than expected
if (theArgIndex >= theMaxArgs)
{
return false;
}
TCollection_AsciiString aStrCommand = theArgsArray->Value(theArgIndex);
aStrCommand.LowerCase();
if (aStrCommand.Search(theCommand) != 1 || theArgIndex + (theArgCount - 1) >= theMaxArgs)
{
return false;
}
// go to the first data element
theArgIndex++;
// check data if it can be converted to numeric
for (int aElement = 0; aElement < theArgCount; aElement++, theArgIndex++)
{
aStrCommand = theArgsArray->Value(theArgIndex);
if (!aStrCommand.IsRealValue(true))
{
return false;
}
}
return true;
}
//=================================================================================================
void MyPArrayObject::setColorForShadingAspect(const Quantity_Color& theColor)
{
if (myDrawer->SetupOwnShadingAspect())
{
replaceShadingAspect();
}
myDrawer->ShadingAspect()->SetColor(theColor);
}
//=================================================================================================
void MyPArrayObject::replaceShadingAspect()
{
if (!myDrawer->Link())
{
return;
}
NCollection_DataMap<occ::handle<Graphic3d_Aspects>, occ::handle<Graphic3d_Aspects>>
anAspectReplacementMap;
anAspectReplacementMap.Bind(myDrawer->Link()->ShadingAspect()->Aspect(),
myDrawer->ShadingAspect()->Aspect());
replaceAspects(anAspectReplacementMap);
}
//=============================================================================
// function : VDrawPArray
// purpose : Draws primitives array from list of vertexes, bounds, edges
//=============================================================================
static int VDrawPArray(Draw_Interpretor& di, int argc, const char** argv)
{
occ::handle<AIS_InteractiveContext> aContextAIS = ViewerTest::GetAISContext();
if (aContextAIS.IsNull())
{
Message::SendFail("Error: no active Viewer");
return 1;
}
else if (argc < 3)
{
Message::SendFail("Syntax error: wrong number of arguments");
return 1;
}
// read the arguments
int anArgIndex = 1;
TCollection_AsciiString aName(argv[anArgIndex++]);
TCollection_AsciiString anArrayType(argv[anArgIndex++]);
anArrayType.LowerCase();
occ::handle<MyPArrayObject> aPObject;
if (anArrayType == "-shape")
{
const char* aShapeName = argv[anArgIndex++];
TopoDS_Shape aShape = DBRep::Get(aShapeName);
occ::handle<Graphic3d_ArrayOfPrimitives> aTris = StdPrs_ShadedShape::FillTriangles(aShape);
if (aShape.IsNull())
{
Message::SendFail() << "Syntax error: shape '" << aShapeName << "' is not found";
return 1;
}
else if (aTris.IsNull())
{
Message::SendFail() << "Syntax error: shape '" << aShapeName << "' is not triangulated";
return 1;
}
aPObject = new MyPArrayObject(aTris);
ViewerTest::Display(aName, aPObject);
return 0;
}
else if (anArrayType == "-patch" || anArrayType == "-modify" || anArrayType == "-edit")
{
if (argc >= 3)
{
anArrayType = argv[anArgIndex++];
anArrayType.LowerCase();
}
if (GetMapOfAIS().IsBound2(aName))
{
aPObject = occ::down_cast<MyPArrayObject>(GetMapOfAIS().Find2(aName));
}
if (aPObject.IsNull())
{
Message::SendFail() << "Syntax error: object '" << aName << "' cannot be found";
return 1;
}
}
bool hasVertex = false;
Graphic3d_TypeOfPrimitiveArray aPrimType = Graphic3d_TOPA_UNDEFINED;
if (anArrayType == "points")
{
aPrimType = Graphic3d_TOPA_POINTS;
}
else if (anArrayType == "segments")
{
aPrimType = Graphic3d_TOPA_SEGMENTS;
}
else if (anArrayType == "polylines")
{
aPrimType = Graphic3d_TOPA_POLYLINES;
}
else if (anArrayType == "triangles")
{
aPrimType = Graphic3d_TOPA_TRIANGLES;
}
else if (anArrayType == "trianglefans")
{
aPrimType = Graphic3d_TOPA_TRIANGLEFANS;
}
else if (anArrayType == "trianglestrips")
{
aPrimType = Graphic3d_TOPA_TRIANGLESTRIPS;
}
else if (anArrayType == "quads")
{
aPrimType = Graphic3d_TOPA_QUADRANGLES;
}
else if (anArrayType == "quadstrips")
{
aPrimType = Graphic3d_TOPA_QUADRANGLESTRIPS;
}
else if (anArrayType == "polygons")
{
aPrimType = Graphic3d_TOPA_POLYGONS;
}
if (aPrimType == Graphic3d_TOPA_UNDEFINED)
{
Message::SendFail("Syntax error: unexpected type of primitives array");
return 1;
}
int aLowerArg = anArgIndex;
occ::handle<NCollection_HArray1<TCollection_AsciiString>> anArgsArray =
new NCollection_HArray1<TCollection_AsciiString>(0, argc - 3);
for (; anArgIndex < argc; ++anArgIndex)
{
TCollection_AsciiString aCommand(argv[anArgIndex]);
aCommand.LowerCase();
if (!aCommand.IsAscii())
{
di << "Unexpected argument: #" << anArgIndex - 1 << " , "
<< "should be an array element: 'v', 'b', 'e' \n";
break;
}
if (aCommand == "v")
{
hasVertex = true;
}
anArgsArray->SetValue(anArgIndex - aLowerArg, aCommand);
}
if (!hasVertex)
{
di << "You should pass any vertices in the list of array elements\n";
return 1;
}
occ::handle<Graphic3d_AspectMarker3d> anAspPoints;
if (aPrimType == Graphic3d_TOPA_POINTS)
{
anAspPoints = new Graphic3d_AspectMarker3d(Aspect_TOM_POINT, Quantity_NOC_YELLOW, 1.0f);
}
// create primitives array object
if (aPObject.IsNull())
{
// register the object in map
aPObject = new MyPArrayObject(aPrimType, anArgsArray, anAspPoints);
VDisplayAISObject(aName, aPObject);
}
else
{
aPObject->Init(aPrimType, anArgsArray, anAspPoints, true);
ViewerTest::CurrentView()->Redraw();
}
return 0;
}
namespace
{
//! Auxiliary function for parsing translation vector - either 2D or 3D.
static int parseTranslationVec(int theArgNb, const char** theArgVec, gp_Vec& theVec)
{
if (theArgNb < 2)
{
return 0;
}
TCollection_AsciiString anX(theArgVec[0]);
TCollection_AsciiString anY(theArgVec[1]);
if (!anX.IsRealValue(true) || !anY.IsRealValue(true))
{
return 0;
}
theVec.SetX(anX.RealValue());
theVec.SetY(anY.RealValue());
if (theArgNb >= 3)
{
TCollection_AsciiString anZ(theArgVec[2]);
if (anZ.IsRealValue(true))
{
theVec.SetZ(anZ.RealValue());
return 3;
}
}
return 2;
}
} // namespace
//=======================================================================
// function : VSetLocation
// purpose : Change location of AIS interactive object
//=======================================================================
static int VSetLocation(Draw_Interpretor& theDI, int theArgNb, const char** theArgVec)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
bool toPrintInfo = true;
occ::handle<AIS_InteractiveObject> anObj;
TCollection_AsciiString aCmdName(theArgVec[0]);
aCmdName.LowerCase();
for (int anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
TCollection_AsciiString anArg = theArgVec[anArgIter];
anArg.LowerCase();
if (anUpdateTool.parseRedrawMode(anArg))
{
continue;
}
else if (anObj.IsNull())
{
const TCollection_AsciiString aName(theArgVec[anArgIter]);
GetMapOfAIS().Find2(aName, anObj);
if (anObj.IsNull())
{
Message::SendFail() << "Error: object '" << aName << "' is not displayed";
return 1;
}
}
else if (anArg == "-reset")
{
toPrintInfo = false;
aContext->SetLocation(anObj, gp_Trsf());
}
else if (anArg == "-copyfrom" || anArg == "-copy")
{
if (anArgIter + 1 >= theArgNb)
{
Message::SendFail() << "Syntax error at '" << anArg << "'";
return 1;
}
const TCollection_AsciiString aName2(theArgVec[anArgIter + 1]);
occ::handle<AIS_InteractiveObject> anObj2;
GetMapOfAIS().Find2(aName2, anObj2);
if (anObj2.IsNull())
{
Message::SendFail() << "Error: object '" << aName2 << "' is not displayed";
return 1;
}
++anArgIter;
aContext->SetLocation(anObj, anObj2->LocalTransformation());
}
else if (anArg == "-rotate" || anArg == "-prerotate")
{
toPrintInfo = false;
if (anArgIter + 7 >= theArgNb)
{
Message::SendFail() << "Syntax error at '" << anArg << "'";
return 1;
}
gp_Trsf aTrsf;
aTrsf.SetRotation(gp_Ax1(gp_Pnt(Draw::Atof(theArgVec[anArgIter + 1]),
Draw::Atof(theArgVec[anArgIter + 2]),
Draw::Atof(theArgVec[anArgIter + 3])),
gp_Vec(Draw::Atof(theArgVec[anArgIter + 4]),
Draw::Atof(theArgVec[anArgIter + 5]),
Draw::Atof(theArgVec[anArgIter + 6]))),
Draw::Atof(theArgVec[anArgIter + 7]) * (M_PI / 180.0));
anArgIter += 7;
if (anArg == "-prerotate")
{
aTrsf = anObj->LocalTransformation() * aTrsf;
}
else
{
aTrsf = aTrsf * anObj->LocalTransformation();
}
aContext->SetLocation(anObj, aTrsf);
}
else if (anArg == "-translate" || anArg == "-pretranslate")
{
toPrintInfo = false;
gp_Vec aLocVec;
int aNbParsed =
parseTranslationVec(theArgNb - anArgIter - 1, theArgVec + anArgIter + 1, aLocVec);
anArgIter += aNbParsed;
if (aNbParsed == 0)
{
Message::SendFail() << "Syntax error at '" << anArg << "'";
return 1;
}
gp_Trsf aTrsf;
aTrsf.SetTranslationPart(aLocVec);
if (anArg == "-pretranslate")
{
aTrsf = anObj->LocalTransformation() * aTrsf;
}
else
{
aTrsf = aTrsf * anObj->LocalTransformation();
}
aContext->SetLocation(anObj, aTrsf);
}
else if (anArg == "-scale" || anArg == "-prescale" || anArg == "-setscale")
{
toPrintInfo = false;
gp_XYZ aScaleLoc;
double aScale = 1.0;
bool toPrintScale = true;
bool hasScaleLoc = false;
if (anArgIter + 4 < theArgNb)
{
TCollection_AsciiString aScaleArgs[4] = {TCollection_AsciiString(theArgVec[anArgIter + 1]),
TCollection_AsciiString(theArgVec[anArgIter + 2]),
TCollection_AsciiString(theArgVec[anArgIter + 3]),
TCollection_AsciiString(theArgVec[anArgIter + 4])};
int aScaleArgIter = 0;
for (; aScaleArgIter < 4; ++aScaleArgIter)
{
if (!aScaleArgs[aScaleArgIter].IsRealValue(true))
{
break;
}
}
if (aScaleArgIter == 4)
{
aScaleLoc.SetCoord(aScaleArgs[0].RealValue(),
aScaleArgs[1].RealValue(),
aScaleArgs[2].RealValue());
aScale = aScaleArgs[3].RealValue();
anArgIter += 4;
toPrintScale = false;
hasScaleLoc = true;
}
else if (aScaleArgIter >= 1)
{
aScale = aScaleArgs[0].RealValue();
++anArgIter;
toPrintScale = false;
}
}
else if (anArgIter + 1 < theArgNb)
{
TCollection_AsciiString aScaleArg(theArgVec[anArgIter + 1]);
if (aScaleArg.IsRealValue(true))
{
aScale = aScaleArg.RealValue();
++anArgIter;
toPrintScale = false;
}
}
if (toPrintScale)
{
if (anArg == "-setscale" || anArg == "-prescale")
{
Message::SendFail() << "Syntax error at '" << anArg << "'";
return 1;
}
char aText[1024];
Sprintf(aText, "%g ", anObj->LocalTransformation().ScaleFactor());
theDI << aText;
continue;
}
if (anArg == "-setscale")
{
gp_Trsf aTrsf = anObj->LocalTransformation();
if (hasScaleLoc)
{
aTrsf.SetScale(aScaleLoc, aScale);
}
else
{
aTrsf.SetScaleFactor(aScale);
}
aContext->SetLocation(anObj, aTrsf);
}
else
{
gp_Trsf aTrsf;
if (hasScaleLoc)
{
aTrsf.SetScale(aScaleLoc, aScale);
}
else
{
aTrsf.SetScaleFactor(aScale);
}
if (anArg == "-prescale")
{
aTrsf = anObj->LocalTransformation() * aTrsf;
}
else
{
aTrsf = aTrsf * anObj->LocalTransformation();
}
aContext->SetLocation(anObj, aTrsf);
}
}
else if (anArg == "-mirror" || anArg == "-premirror")
{
toPrintInfo = false;
if (anArgIter + 6 >= theArgNb)
{
Message::SendFail() << "Syntax error at '" << anArg << "'";
return 1;
}
gp_Trsf aTrsf;
aTrsf.SetMirror(gp_Ax2(gp_Pnt(Draw::Atof(theArgVec[theArgNb - 6]),
Draw::Atof(theArgVec[theArgNb - 5]),
Draw::Atof(theArgVec[theArgNb - 4])),
gp_Vec(Draw::Atof(theArgVec[theArgNb - 3]),
Draw::Atof(theArgVec[theArgNb - 2]),
Draw::Atof(theArgVec[theArgNb - 1]))));
anArgIter += 6;
if (anArg == "-premirror")
{
aTrsf = anObj->LocalTransformation() * aTrsf;
}
else
{
aTrsf = aTrsf * anObj->LocalTransformation();
}
aContext->SetLocation(anObj, aTrsf);
}
else if (anArg == "-setrotation" || anArg == "-rotation")
{
toPrintInfo = false;
if (anArgIter + 4 < theArgNb)
{
TCollection_AsciiString aQuatArgs[4] = {TCollection_AsciiString(theArgVec[anArgIter + 1]),
TCollection_AsciiString(theArgVec[anArgIter + 2]),
TCollection_AsciiString(theArgVec[anArgIter + 3]),
TCollection_AsciiString(theArgVec[anArgIter + 4])};
int aQuatArgIter = 0;
for (; aQuatArgIter < 4; ++aQuatArgIter)
{
if (!aQuatArgs[aQuatArgIter].IsRealValue(true))
{
break;
}
}
if (aQuatArgIter == 4)
{
anArgIter += 4;
const gp_Quaternion aQuat(aQuatArgs[0].RealValue(),
aQuatArgs[1].RealValue(),
aQuatArgs[2].RealValue(),
aQuatArgs[3].RealValue());
gp_Trsf aTrsf = anObj->LocalTransformation();
aTrsf.SetRotationPart(aQuat);
aContext->SetLocation(anObj, aTrsf);
continue;
}
else if (anArg == "-setrotation")
{
Message::SendFail() << "Syntax error at '" << anArg << "'";
return 1;
}
}
char aText[1024];
const gp_Quaternion aQuat = anObj->LocalTransformation().GetRotation();
Sprintf(aText, "%g %g %g %g ", aQuat.X(), aQuat.Y(), aQuat.Z(), aQuat.W());
theDI << aText;
}
else if (anArg == "-setlocation" || anArg == "-location")
{
toPrintInfo = false;
gp_Vec aLocVec;
int aNbParsed =
parseTranslationVec(theArgNb - anArgIter - 1, theArgVec + anArgIter + 1, aLocVec);
anArgIter += aNbParsed;
if (aNbParsed != 0)
{
gp_Trsf aTrsf = anObj->LocalTransformation();
aTrsf.SetTranslationPart(aLocVec);
aContext->SetLocation(anObj, aTrsf);
}
else if (anArg == "-setlocation")
{
Message::SendFail() << "Syntax error at '" << anArg << "'";
return 1;
}
char aText[1024];
const gp_XYZ aLoc = anObj->LocalTransformation().TranslationPart();
Sprintf(aText, "%g %g %g ", aLoc.X(), aLoc.Y(), aLoc.Z());
theDI << aText;
}
else if (aCmdName == "vsetlocation")
{
// compatibility with old syntax
gp_Vec aLocVec;
int aNbParsed = parseTranslationVec(theArgNb - anArgIter, theArgVec + anArgIter, aLocVec);
if (aNbParsed == 0)
{
Message::SendFail() << "Syntax error at '" << anArg << "'";
return 1;
}
anArgIter = anArgIter + aNbParsed - 1;
gp_Trsf aTrsf;
aTrsf.SetTranslationPart(aLocVec);
aContext->SetLocation(anObj, aTrsf);
toPrintInfo = false;
}
else
{
Message::SendFail() << "Error: unknown argument '" << anArg << "'";
return 1;
}
}
if (anObj.IsNull())
{
Message::SendFail("Syntax error - wrong number of arguments");
return 1;
}
else if (!toPrintInfo)
{
return 0;
}
const gp_Trsf aTrsf = anObj->LocalTransformation();
const gp_XYZ aLoc = aTrsf.TranslationPart();
const gp_Quaternion aRot = aTrsf.GetRotation();
char aText[4096];
Sprintf(aText,
"Location: %g %g %g\n"
"Rotation: %g %g %g %g\n"
"Scale: %g\n",
aLoc.X(),
aLoc.Y(),
aLoc.Z(),
aRot.X(),
aRot.Y(),
aRot.Z(),
aRot.W(),
aTrsf.ScaleFactor());
theDI << aText;
return 0;
}
//! Find displayed object.
static occ::handle<AIS_InteractiveObject> findConnectedObject(
const TCollection_AsciiString& theName)
{
occ::handle<AIS_InteractiveObject> aPrs;
if (!GetMapOfAIS().Find2(theName, aPrs))
{
return occ::handle<AIS_InteractiveObject>();
}
if (occ::handle<AIS_ConnectedInteractive> aConnected =
occ::down_cast<AIS_ConnectedInteractive>(aPrs))
{
return aConnected;
}
else if (occ::handle<AIS_MultipleConnectedInteractive> aMultiCon =
occ::down_cast<AIS_MultipleConnectedInteractive>(aPrs))
{
return aMultiCon;
}
// replace already displayed object with connected one
TheAISContext()->Remove(aPrs, false);
occ::handle<AIS_ConnectedInteractive> aConnected = new AIS_ConnectedInteractive();
if (aPrs->HasDisplayMode())
{
aConnected->SetDisplayMode(aPrs->DisplayMode());
}
aConnected->Connect(aPrs, aPrs->LocalTransformationGeom());
if (!aPrs->TransformPersistence().IsNull())
{
aConnected->SetTransformPersistence(aPrs->TransformPersistence());
}
ViewerTest::Display(theName, aConnected, false);
return aConnected;
}
//===============================================================================================
// function : VConnect
// purpose : Creates and displays AIS_ConnectedInteractive object from input object and location
//===============================================================================================
static int VConnect(Draw_Interpretor& /*di*/, int argc, const char** argv)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (argc < 6)
{
Message::SendFail("Syntax error: expect at least 5 arguments");
return 1;
}
// Get values
int anArgIter = 1;
const TCollection_AsciiString aName(argv[anArgIter++]);
occ::handle<AIS_MultipleConnectedInteractive> aMultiConObject;
TCollection_AsciiString aColorString(argv[argc - 1]);
Quantity_Color aColor;
bool hasColor = false;
if (aColorString.Search("color=") != -1)
{
hasColor = true;
aColorString.Remove(1, 6);
if (!Quantity_Color::ColorFromName(aColorString.ToCString(), aColor))
{
Message::SendFail() << "Syntax error at " << aColorString;
return 1;
}
}
const int aNbShapes = hasColor ? (argc - 1) : argc;
for (int i = 5; i < aNbShapes; ++i)
{
TCollection_AsciiString anOriginObjectName(argv[i]);
occ::handle<AIS_InteractiveObject> anObject;
if (aName.IsEqual(anOriginObjectName))
{
Message::SendFail("Syntax error: equal names for connected objects");
continue;
}
anObject = findConnectedObject(anOriginObjectName);
if (anObject.IsNull())
{
TopoDS_Shape aTDShape = DBRep::Get(anOriginObjectName);
if (aTDShape.IsNull())
{
Message::SendFail() << "Syntax error: object " << anOriginObjectName << " doesn't exist";
return 1;
}
occ::handle<AIS_Shape> aShapePrs = new AIS_Shape(aTDShape);
occ::handle<AIS_ConnectedInteractive> aConnectedOrig = new AIS_ConnectedInteractive();
aConnectedOrig->Connect(aShapePrs);
anObject = aConnectedOrig;
aContext->Load(anObject);
anObject->SetColor(aColor);
}
if (aMultiConObject.IsNull())
{
aMultiConObject = new AIS_MultipleConnectedInteractive();
}
aMultiConObject->Connect(anObject);
}
if (aMultiConObject.IsNull())
{
Message::SendFail("Syntax error: can't connect input objects");
return 1;
}
// Create transformation
gp_Trsf aTrsf;
aTrsf.SetTranslationPart(gp_Vec(Draw::Atof(argv[anArgIter + 0]),
Draw::Atof(argv[anArgIter + 1]),
Draw::Atof(argv[anArgIter + 2])));
TopLoc_Location aLocation(aTrsf);
anArgIter += 3;
aMultiConObject->SetLocalTransformation(aTrsf);
ViewerTest::Display(aName, aMultiConObject, true);
return 0;
}
//===============================================================================================
// function : VConnectTo
// purpose : Creates and displays AIS_ConnectedInteractive object from input object and location
//===============================================================================================
static int VConnectTo(Draw_Interpretor& /*di*/, int argc, const char** argv)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (argc != 6 && argc != 7)
{
Message::SendFail("Syntax error: expect at least 5 arguments");
return 1;
}
int anArgIter = 1;
TCollection_AsciiString aName(argv[anArgIter++]);
occ::handle<AIS_InteractiveObject> anOriginObject;
TCollection_AsciiString anOriginObjectName(argv[5]);
if (aName.IsEqual(anOriginObjectName))
{
Message::SendFail("Syntax error: equal names for connected objects");
return 1;
}
anOriginObject = findConnectedObject(anOriginObjectName);
if (anOriginObject.IsNull())
{
TopoDS_Shape aTDShape = DBRep::Get(anOriginObjectName);
if (aTDShape.IsNull())
{
Message::SendFail() << "Syntax error: object " << anOriginObjectName << " doesn't exist";
return 1;
}
occ::handle<AIS_Shape> aShapePrs = new AIS_Shape(aTDShape);
occ::handle<AIS_ConnectedInteractive> aConnectedOrig = new AIS_ConnectedInteractive();
aConnectedOrig->Connect(aShapePrs);
anOriginObject = aConnectedOrig;
GetMapOfAIS().Bind(aConnectedOrig, anOriginObjectName);
}
// Create transformation
gp_Trsf aTrsf;
aTrsf.SetTranslationPart(gp_Vec(Draw::Atof(argv[anArgIter + 0]),
Draw::Atof(argv[anArgIter + 1]),
Draw::Atof(argv[anArgIter + 2])));
anArgIter += 3;
occ::handle<AIS_ConnectedInteractive> aConnected = new AIS_ConnectedInteractive();
aConnected->Connect(anOriginObject, aTrsf);
if (argc == 7)
{
TCollection_AsciiString anArg = argv[6];
anArg.LowerCase();
if (anArg == "-nodisplay")
{
// bind connected object without displaying it
occ::handle<AIS_InteractiveObject> anObj;
if (GetMapOfAIS().Find2(aName, anObj))
{
TheAISContext()->Remove(anObj, false);
GetMapOfAIS().UnBind2(aName);
}
GetMapOfAIS().Bind(aConnected, aName);
return 0;
}
if (!anUpdateTool.parseRedrawMode(anArg))
{
Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
return 1;
}
}
ViewerTest::Display(aName, aConnected, false);
return 0;
}
//=================================================================================================
static int VDisconnect(Draw_Interpretor& di, int argc, const char** argv)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (argc != 3)
{
Message::SendFail() << "Syntax error: wrong number of arguments.\nUsage: " << argv[0]
<< " name object";
return 1;
}
TCollection_AsciiString aName(argv[1]);
TCollection_AsciiString anObject(argv[2]);
int anObjectNumber = Draw::Atoi(argv[2]);
// find objects
NCollection_DoubleMap<occ::handle<AIS_InteractiveObject>, TCollection_AsciiString>& aMap =
GetMapOfAIS();
occ::handle<AIS_MultipleConnectedInteractive> anAssembly;
if (!aMap.IsBound2(aName))
{
Message::SendFail("Error: no active viewer");
return 1;
}
anAssembly = occ::down_cast<AIS_MultipleConnectedInteractive>(aMap.Find2(aName));
if (anAssembly.IsNull())
{
di << "Not an assembly\n";
return 1;
}
occ::handle<AIS_InteractiveObject> anIObj;
if (!aMap.Find2(anObject, anIObj))
{
// try to interpret second argument as child number
if (anObjectNumber > 0 && anObjectNumber <= anAssembly->Children().Length())
{
int aCounter = 1;
for (NCollection_List<occ::handle<PrsMgr_PresentableObject>>::Iterator anIter(
anAssembly->Children());
anIter.More();
anIter.Next())
{
if (aCounter == anObjectNumber)
{
anIObj = occ::down_cast<AIS_InteractiveObject>(anIter.Value());
break;
}
++aCounter;
}
}
else
{
Message::SendFail("Error: no active viewer");
return 1;
}
}
aContext->Disconnect(anAssembly, anIObj);
aContext->UpdateCurrentViewer();
return 0;
}
//=================================================================================================
static int VAddConnected(Draw_Interpretor&, int argc, const char** argv)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (argc != 6)
{
Message::SendFail("Syntax error: expect 5 arguments");
return 1;
}
const TCollection_AsciiString aName(argv[1]);
const double aX = Draw::Atof(argv[2]);
const double aY = Draw::Atof(argv[3]);
const double aZ = Draw::Atof(argv[4]);
const TCollection_AsciiString anObjectName(argv[5]);
// find object
NCollection_DoubleMap<occ::handle<AIS_InteractiveObject>, TCollection_AsciiString>& aMap =
GetMapOfAIS();
occ::handle<AIS_MultipleConnectedInteractive> anAssembly;
{
occ::handle<AIS_InteractiveObject> aPrs;
aMap.Find2(aName, aPrs);
anAssembly = occ::down_cast<AIS_MultipleConnectedInteractive>(aPrs);
if (anAssembly.IsNull())
{
Message::SendFail() << "Syntax error: '" << aName << "' is not an assembly";
return 1;
}
}
occ::handle<AIS_InteractiveObject> anIObj = findConnectedObject(anObjectName);
if (anIObj.IsNull())
{
Message::SendFail() << "Syntax error: '" << anObjectName << "' is not displayed";
return 1;
}
gp_Trsf aTrsf;
aTrsf.SetTranslation(gp_Vec(aX, aY, aZ));
anAssembly->Connect(anIObj, aTrsf);
TheAISContext()->Display(anAssembly, false);
TheAISContext()->RecomputeSelectionOnly(anAssembly);
aContext->UpdateCurrentViewer();
return 0;
}
//=================================================================================================
static int VListConnected(Draw_Interpretor& /*di*/, int argc, const char** argv)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (argc != 2)
{
Message::SendFail() << "Syntax error: wrong number of arguments.\nUsage: " << argv[0]
<< " name";
return 1;
}
TCollection_AsciiString aName(argv[1]);
// find object
NCollection_DoubleMap<occ::handle<AIS_InteractiveObject>, TCollection_AsciiString>& aMap =
GetMapOfAIS();
occ::handle<AIS_MultipleConnectedInteractive> anAssembly;
if (!aMap.IsBound2(aName))
{
Message::SendFail("Error: no active viewer");
return 1;
}
anAssembly = occ::down_cast<AIS_MultipleConnectedInteractive>(aMap.Find2(aName));
if (anAssembly.IsNull())
{
Message::SendFail("Syntax error: Not an assembly");
return 1;
}
std::cout << "Children of " << aName << ":\n";
int aCounter = 1;
for (NCollection_List<occ::handle<PrsMgr_PresentableObject>>::Iterator anIter(
anAssembly->Children());
anIter.More();
anIter.Next())
{
occ::handle<AIS_InteractiveObject> anObj =
occ::down_cast<AIS_InteractiveObject>(anIter.Value());
if (GetMapOfAIS().IsBound1(anObj))
{
TCollection_AsciiString aCuurrentName = GetMapOfAIS().Find1(anObj);
std::cout << aCounter << ") " << aCuurrentName << " ("
<< anIter.Value()->DynamicType()->Name() << ")";
}
std::cout << aCounter << ") " << anIter.Value()->DynamicType()->Name();
occ::handle<AIS_ConnectedInteractive> aConnected =
occ::down_cast<AIS_ConnectedInteractive>(anIter.Value());
if (!aConnected.IsNull() && !aConnected->ConnectedTo().IsNull()
&& aMap.IsBound1(aConnected->ConnectedTo()))
{
std::cout << " connected to " << aMap.Find1(aConnected->ConnectedTo());
}
std::cout << '\n';
++aCounter;
}
return 0;
}
//=================================================================================================
static int VChild(Draw_Interpretor&, int theNbArgs, const char** theArgVec)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
int toAdd = -1;
occ::handle<AIS_InteractiveObject> aParent;
bool hasActions = false;
int toInheritTrsf = -1;
ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
for (int anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArg(theArgVec[anArgIter]);
anArg.LowerCase();
if (anUpdateTool.parseRedrawMode(anArg))
{
continue;
}
else if (anArg == "-add")
{
toAdd = 1;
continue;
}
else if (anArg == "-remove")
{
toAdd = 0;
continue;
}
else if (anArg == "-inheritparenttrsf" || anArg == "-inheritparentloc"
|| anArg == "-inheritparentlocation" || anArg == "-inheritparent"
|| anArg == "-noinheritparenttrsf" || anArg == "-noinheritparentloc"
|| anArg == "-noinheritparentlocation" || anArg == "-noinheritparent"
|| anArg == "-ignoreparenttrsf" || anArg == "-ignoreparentloc"
|| anArg == "-ignoreparentlocation" || anArg == "-ignoreparent")
{
bool aVal = true;
if (anArgIter + 1 < theNbArgs && Draw::ParseOnOff(theArgVec[anArgIter + 1], aVal))
{
++anArgIter;
}
if (anArg.StartsWith("-no") || anArg.StartsWith("-ignore"))
{
aVal = !aVal;
}
toInheritTrsf = aVal ? 1 : 0;
continue;
}
occ::handle<AIS_InteractiveObject> aChild;
if (!GetMapOfAIS().Find2(theArgVec[anArgIter], aChild))
{
Message::SendFail() << "Syntax error: object '" << theArgVec[anArgIter] << "' is not found";
return 1;
}
if (aParent.IsNull())
{
aParent = aChild;
}
else if (toAdd == -1)
{
Message::SendFail("Syntax error: no action specified");
return 1;
}
else
{
hasActions = true;
if (toAdd == 1)
{
if (toInheritTrsf == 0)
{
aParent->AddChildWithCurrentTransformation(aChild);
}
else
{
aParent->AddChild(aChild);
}
}
else
{
if (toInheritTrsf == 0)
{
aParent->RemoveChildWithRestoreTransformation(aChild);
}
else
{
aParent->RemoveChild(aChild);
}
}
}
}
if (!hasActions)
{
Message::SendFail("Syntax error: not enough arguments");
return 1;
}
return 0;
}
//=================================================================================================
static int VParent(Draw_Interpretor&, int theNbArgs, const char** theArgVec)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (theNbArgs < 2)
{
Message::SendFail("Syntax error: wrong number of arguments");
return 1;
}
TCollection_AsciiString aName(theArgVec[1]);
occ::handle<AIS_InteractiveObject> aParent;
if (!GetMapOfAIS().Find2(theArgVec[1], aParent))
{
Message::SendFail() << "Syntax error: object '" << theArgVec[1] << "' is not found";
return 1;
}
ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
for (int anArgIter = 2; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArg(theArgVec[anArgIter]);
anArg.LowerCase();
if (anArg == "-ignorevisu")
{
aParent->SetPropagateVisualState(false);
}
}
return 0;
}
//=================================================================================================
static int VSetSelectionMode(Draw_Interpretor& /*di*/, int theNbArgs, const char** theArgv)
{
// Check errors
occ::handle<AIS_InteractiveContext> anAISContext = ViewerTest::GetAISContext();
if (anAISContext.IsNull())
{
Message::SendFail("Error: no active Viewer");
return 1;
}
NCollection_Sequence<TCollection_AsciiString> anObjNames;
int aSelectionMode = -1;
bool toTurnOn = true;
AIS_SelectionModesConcurrency aSelModeConcurrency = AIS_SelectionModesConcurrency_GlobalOrLocal;
for (int anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArgCase(theArgv[anArgIter]);
anArgCase.LowerCase();
if (anArgCase == "-set" || anArgCase == "-replace" || anArgCase == "-single"
|| anArgCase == "-exclusive")
{
aSelModeConcurrency = AIS_SelectionModesConcurrency_Single;
}
else if (anArgCase == "-add" || anArgCase == "-combine" || anArgCase == "-combination"
|| anArgCase == "-multiple")
{
aSelModeConcurrency = AIS_SelectionModesConcurrency_Multiple;
}
else if (anArgCase == "-globalorlocal" || anArgCase == "-localorglobal")
{
aSelModeConcurrency = AIS_SelectionModesConcurrency_GlobalOrLocal;
}
else
{
anObjNames.Append(theArgv[anArgIter]);
}
}
if (anObjNames.Size() < 2 || !Draw::ParseOnOff(anObjNames.Last().ToCString(), toTurnOn))
{
Message::SendFail("Syntax error: wrong number of arguments");
return 1;
}
anObjNames.Remove(anObjNames.Upper());
{
const TCollection_AsciiString aSelModeString = anObjNames.Last();
anObjNames.Remove(anObjNames.Upper());
TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE;
if (aSelModeString.IsIntegerValue())
{
aSelectionMode = aSelModeString.IntegerValue();
}
else if (TopAbs::ShapeTypeFromString(aSelModeString.ToCString(), aShapeType))
{
aSelectionMode = AIS_Shape::SelectionMode(aShapeType);
}
else
{
Message::SendFail() << "Syntax error: unknown selection mode '" << aSelModeString << "'";
return 1;
}
}
NCollection_List<occ::handle<AIS_InteractiveObject>> aTargetIOs;
for (NCollection_Sequence<TCollection_AsciiString>::Iterator anObjIter(anObjNames);
anObjIter.More();
anObjIter.Next())
{
const TCollection_AsciiString& aNameIO = anObjIter.Value();
occ::handle<AIS_InteractiveObject> anIO;
GetMapOfAIS().Find2(aNameIO, anIO);
if (anIO.IsNull())
{
Message::SendFail() << "Syntax error: undefined presentable object " << aNameIO;
return 1;
}
aTargetIOs.Append(anIO);
}
if (aTargetIOs.IsEmpty())
{
anAISContext->DisplayedObjects(aTargetIOs);
}
for (NCollection_List<occ::handle<AIS_InteractiveObject>>::Iterator aTargetIt(aTargetIOs);
aTargetIt.More();
aTargetIt.Next())
{
const occ::handle<AIS_InteractiveObject>& anIO = aTargetIt.Value();
anAISContext->SetSelectionModeActive(anIO, aSelectionMode, toTurnOn, aSelModeConcurrency);
}
return 0;
}
//=================================================================================================
static int VSelectionNext(Draw_Interpretor& /*theDI*/,
int /*theArgsNb*/,
const char** /*theArgVec*/)
{
// Check errors
occ::handle<AIS_InteractiveContext> anAISContext = ViewerTest::GetAISContext();
occ::handle<V3d_View> aView = ViewerTest::CurrentView();
if (anAISContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
anAISContext->HilightNextDetected(aView);
return 0;
}
//=================================================================================================
static int VSelectionPrevious(Draw_Interpretor& /*theDI*/,
int /*theArgsNb*/,
const char** /*theArgVec*/)
{
// Check errors
occ::handle<AIS_InteractiveContext> anAISContext = ViewerTest::GetAISContext();
occ::handle<V3d_View> aView = ViewerTest::CurrentView();
if (anAISContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
anAISContext->HilightPreviousDetected(aView);
return 0;
}
//=================================================================================================
static int VTriangle(Draw_Interpretor& /*di*/, int argc, const char** argv)
{
const bool isTri = TCollection_AsciiString(argv[0]) == "vtriangle";
occ::handle<Graphic3d_ArrayOfPrimitives> aPrims;
if (isTri)
{
aPrims = new Graphic3d_ArrayOfTriangles(3);
}
else
{
aPrims = new Graphic3d_ArrayOfSegments(2);
}
if (argc != (2 + aPrims->VertexNumberAllocated()))
{
Message::SendFail("Syntax error: wrong number of arguments");
return 1;
}
gp_Pnt aPnts[3];
for (int aPntIter = 0; aPntIter < aPrims->VertexNumberAllocated(); ++aPntIter)
{
const TCollection_AsciiString aName(argv[2 + aPntIter]);
if (occ::handle<AIS_Point> aPntPrs = occ::down_cast<AIS_Point>(
GetMapOfAIS().IsBound2(aName) ? GetMapOfAIS().Find2(aName) : nullptr))
{
aPnts[aPntIter] = aPntPrs->Component()->Pnt();
}
else
{
TopoDS_Shape aShape = DBRep::Get(argv[2 + aPntIter]);
if (aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX)
{
Message::SendFail() << "Syntax error: argument " << aName << " must be a point";
return 1;
}
aPnts[aPntIter] = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
}
for (int aPnt2Iter = 0; aPnt2Iter < aPntIter; ++aPnt2Iter)
{
if (aPnts[aPnt2Iter].IsEqual(aPnts[aPntIter], Precision::Confusion()))
{
Message::SendFail("Syntax error: points should not be equal");
return 1;
}
}
aPrims->AddVertex(aPnts[aPntIter]);
}
occ::handle<AIS_InteractiveObject> aPrs = new MyPArrayObject(aPrims);
if (!isTri)
{
aPrs->Attributes()->SetupOwnShadingAspect();
aPrs->Attributes()->ShadingAspect()->Aspect()->SetColor(Quantity_NOC_YELLOW);
}
ViewerTest::Display(argv[1], aPrs);
return 0;
}
//===========================================================================
// function : VTorus
// purpose : creates and displays a torus or torus segment
//===========================================================================
static int VTorus(Draw_Interpretor& /*di*/, int theNbArgs, const char** theArgVec)
{
if (ViewerTest::GetAISContext().IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
TCollection_AsciiString aName;
int aNbSlices = 100, aNbStacks = 100;
double aMajorRad = -1.0, aMinorRad = -1.0;
double aPipeAngle = 360.0, aSegAngle1 = 0.0, aSegAngle2 = 360.0;
double anAngles[3] = {-1.0, -1.0, -1.0};
ViewerTest_AutoUpdater anUpdateTool(ViewerTest::GetAISContext(), ViewerTest::CurrentView());
for (int anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArg(theArgVec[anArgIter]);
anArg.LowerCase();
if (anUpdateTool.parseRedrawMode(anArg))
{
continue;
}
else if (anArgIter + 1 < theNbArgs && (anArg == "-nbslices" || anArg == "-slices")
&& Draw::ParseInteger(theArgVec[anArgIter + 1], aNbSlices))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && (anArg == "-nbstacks" || anArg == "-stacks")
&& Draw::ParseInteger(theArgVec[anArgIter + 1], aNbStacks))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && (anArg == "-radius" || anArg == "-majorradius")
&& Draw::ParseReal(theArgVec[anArgIter + 1], aMajorRad))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && (anArg == "-piperadius" || anArg == "-minoradius")
&& Draw::ParseReal(theArgVec[anArgIter + 1], aMinorRad))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && (anArg == "-pipeangle" || anArg == "-angle")
&& Draw::ParseReal(theArgVec[anArgIter + 1], aPipeAngle))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs
&& (anArg == "-segmentanglefrom" || anArg == "-seganglefrom"
|| anArg == "-segmentangle1" || anArg == "-segangle1")
&& Draw::ParseReal(theArgVec[anArgIter + 1], aSegAngle1))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs
&& (anArg == "-segmentangleto" || anArg == "-segangleto" || anArg == "-segmentangle2"
|| anArg == "-segangle2")
&& Draw::ParseReal(theArgVec[anArgIter + 1], aSegAngle2))
{
++anArgIter;
}
else if (aName.IsEmpty())
{
aName = theArgVec[anArgIter];
}
else if (aMajorRad < 0.0 && Draw::ParseReal(theArgVec[anArgIter], aMajorRad))
{
//
}
else if (aMinorRad < 0.0 && Draw::ParseReal(theArgVec[anArgIter], aMinorRad))
{
//
}
else if (anAngles[0] < 0.0 && Draw::ParseReal(theArgVec[anArgIter], anAngles[0]))
{
//
}
else if (anAngles[1] < 0.0 && Draw::ParseReal(theArgVec[anArgIter], anAngles[1]))
{
//
}
else if (anAngles[2] < 0.0 && Draw::ParseReal(theArgVec[anArgIter], anAngles[2]))
{
//
}
else
{
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
return 1;
}
}
if (anAngles[2] > 0.0)
{
aSegAngle1 = anAngles[0];
aSegAngle2 = anAngles[1];
aPipeAngle = anAngles[2];
}
else if (anAngles[1] > 0.0)
{
aSegAngle1 = anAngles[0];
aSegAngle2 = anAngles[1];
}
else if (anAngles[0] > 0.0)
{
aPipeAngle = anAngles[0];
}
aSegAngle1 = aSegAngle1 * (M_PI / 180.0);
aSegAngle2 = aSegAngle2 * (M_PI / 180.0);
aPipeAngle = aPipeAngle * (M_PI / 180.0);
if (aMajorRad <= 0 || aMinorRad <= 0 || aNbSlices <= 0 || aNbStacks <= 0
|| std::abs(aSegAngle2 - aSegAngle1) <= Precision::Angular()
|| std::abs(aPipeAngle) <= Precision::Angular())
{
Message::SendFail("Syntax error: wrong parameters");
return 1;
}
occ::handle<Graphic3d_ArrayOfTriangles> aTriangles = Prs3d_ToolTorus::Create(aMajorRad,
aMinorRad,
aSegAngle1,
aSegAngle2,
aPipeAngle,
aNbSlices,
aNbStacks,
gp_Trsf());
occ::handle<AIS_InteractiveObject> anIO = new MyPArrayObject(aTriangles);
ViewerTest::Display(aName, anIO, false);
return 0;
}
//===========================================================================
// function : VCylinder
// purpose : creates and displays a cylinder
//===========================================================================
static int VCylinder(Draw_Interpretor& /*di*/, int theNbArgs, const char** theArgVec)
{
if (ViewerTest::GetAISContext().IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
TCollection_AsciiString aName;
int aNbSlices = 100, aNbStacks = 1;
double aBotRad = -1.0, aTopRad = -1.0, aHeight = -1.0;
ViewerTest_AutoUpdater anUpdateTool(ViewerTest::GetAISContext(), ViewerTest::CurrentView());
for (int anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArg(theArgVec[anArgIter]);
anArg.LowerCase();
if (anUpdateTool.parseRedrawMode(anArg))
{
continue;
}
else if (anArgIter + 1 < theNbArgs && (anArg == "-nbslices" || anArg == "-slices")
&& Draw::ParseInteger(theArgVec[anArgIter + 1], aNbSlices))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && (anArg == "-nbstacks" || anArg == "-stacks")
&& Draw::ParseInteger(theArgVec[anArgIter + 1], aNbStacks))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && anArg == "-radius"
&& Draw::ParseReal(theArgVec[anArgIter + 1], aBotRad))
{
aTopRad = aBotRad;
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && anArg == "-bottomradius"
&& Draw::ParseReal(theArgVec[anArgIter + 1], aBotRad))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && anArg == "-topradius"
&& Draw::ParseReal(theArgVec[anArgIter + 1], aTopRad))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && anArg == "-height"
&& Draw::ParseReal(theArgVec[anArgIter + 1], aHeight))
{
++anArgIter;
}
else if (aName.IsEmpty())
{
aName = theArgVec[anArgIter];
}
else if (aBotRad < 0.0 && Draw::ParseReal(theArgVec[anArgIter], aBotRad))
{
//
}
else if (aTopRad < 0.0 && Draw::ParseReal(theArgVec[anArgIter], aTopRad))
{
//
}
else if (aHeight < 0.0 && Draw::ParseReal(theArgVec[anArgIter], aHeight))
{
//
}
else
{
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
return 1;
}
}
if (aBotRad < 0 || aTopRad < 0 || aHeight <= 0 || aNbSlices < 3)
{
Message::SendFail("Syntax error: wrong parameters");
return 1;
}
occ::handle<Graphic3d_ArrayOfTriangles> aTriangles =
Prs3d_ToolCylinder::Create(aBotRad, aTopRad, aHeight, aNbSlices, aNbStacks, gp_Trsf());
occ::handle<AIS_InteractiveObject> anIO = new MyPArrayObject(aTriangles);
ViewerTest::Display(aName, anIO, false);
return 0;
}
//=================================================================================================
static int VSphere(Draw_Interpretor& /*di*/, int theNbArgs, const char** theArgVec)
{
if (ViewerTest::GetAISContext().IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
TCollection_AsciiString aName;
int aNbSlices = 100, aNbStacks = 100;
double aRad = -1.0;
ViewerTest_AutoUpdater anUpdateTool(ViewerTest::GetAISContext(), ViewerTest::CurrentView());
for (int anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArg(theArgVec[anArgIter]);
anArg.LowerCase();
if (anUpdateTool.parseRedrawMode(anArg))
{
continue;
}
else if (anArgIter + 1 < theNbArgs && (anArg == "-nbslices" || anArg == "-slices")
&& Draw::ParseInteger(theArgVec[anArgIter + 1], aNbSlices))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && (anArg == "-nbstacks" || anArg == "-stacks")
&& Draw::ParseInteger(theArgVec[anArgIter + 1], aNbStacks))
{
++anArgIter;
}
else if (anArgIter + 1 < theNbArgs && anArg == "-radius"
&& Draw::ParseReal(theArgVec[anArgIter + 1], aRad))
{
++anArgIter;
}
else if (aName.IsEmpty())
{
aName = theArgVec[anArgIter];
}
else if (aRad < 0.0 && Draw::ParseReal(theArgVec[anArgIter], aRad))
{
//
}
else
{
Message::SendFail() << "Syntax error at '" << theArgVec[anArgIter] << "'";
return 1;
}
}
if (aRad <= 0 || aNbSlices <= 0 || aNbStacks <= 0)
{
Message::SendFail("Syntax error: wrong parameters");
return 1;
}
occ::handle<Graphic3d_ArrayOfTriangles> aTriangles =
Prs3d_ToolSphere::Create(aRad, aNbSlices, aNbStacks, gp_Trsf());
occ::handle<AIS_InteractiveObject> anIO = new MyPArrayObject(aTriangles);
ViewerTest::Display(aName, anIO, false);
return 0;
}
//=======================================================================
// function : VObjZLayer
// purpose : Set or get z layer id for presentable object
//=======================================================================
static int VObjZLayer(Draw_Interpretor& di, int argc, const char** argv)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
// get operation
TCollection_AsciiString aOperation;
if (argc >= 2)
{
aOperation = TCollection_AsciiString(argv[1]);
}
// check for correct arguments
if ((argc != 4 || !aOperation.IsEqual("set")) && (argc != 3 || !aOperation.IsEqual("get")))
{
di << "Usage : " << argv[0] << " set/get object [layerid]\n";
di << " set - set layer id for interactive object, layerid - z layer id\n";
di << " get - get layer id of interactive object\n";
di << " argument layerid should be passed for set operation only\n";
return 1;
}
// find object
TCollection_AsciiString aName(argv[2]);
occ::handle<AIS_InteractiveObject> anInterObj;
GetMapOfAIS().Find2(aName, anInterObj);
if (anInterObj.IsNull())
{
Message::SendFail() << "Syntax error: object '" << aName << "' is not displayed";
return 1;
}
// process operation
if (aOperation.IsEqual("set"))
{
int aLayerId = Draw::Atoi(argv[3]);
aContext->SetZLayer(anInterObj, aLayerId);
}
else if (aOperation.IsEqual("get"))
{
di << "Z layer id: " << aContext->GetZLayer(anInterObj);
}
return 0;
}
//=======================================================================
// function : VPolygonOffset
// purpose : Set or get polygon offset parameters
//=======================================================================
static int VPolygonOffset(Draw_Interpretor& /*di*/, int argc, const char** argv)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (argc > 2 && argc != 5)
{
Message::SendFail()
<< "Syntax error: wrong number of arguments.\n"
"Usage: "
<< argv[0]
<< " [object [mode factor units]] - sets/gets polygon offset parameters for an object,"
"without arguments prints the default values";
return 1;
}
// find object
occ::handle<AIS_InteractiveObject> anInterObj;
if (argc >= 2)
{
TCollection_AsciiString aName(argv[1]);
if (!GetMapOfAIS().Find2(aName, anInterObj) || anInterObj.IsNull())
{
Message::SendFail() << "Syntax error: object '" << aName << "' is not displayed";
return 1;
}
}
int aMode;
float aFactor, aUnits;
if (argc == 5)
{
aMode = Draw::Atoi(argv[2]);
aFactor = (float)Draw::Atof(argv[3]);
aUnits = (float)Draw::Atof(argv[4]);
anInterObj->SetPolygonOffsets(aMode, aFactor, aUnits);
aContext->UpdateCurrentViewer();
return 0;
}
else if (argc == 2)
{
if (anInterObj->HasPolygonOffsets())
{
anInterObj->PolygonOffsets(aMode, aFactor, aUnits);
std::cout << "Current polygon offset parameters for " << argv[1] << ":" << '\n';
std::cout << "\tMode: " << aMode << '\n';
std::cout << "\tFactor: " << aFactor << '\n';
std::cout << "\tUnits: " << aUnits << '\n';
return 0;
}
else
{
std::cout << "Specific polygon offset parameters are not set for " << argv[1] << '\n';
}
}
std::cout << "Default polygon offset parameters:" << '\n';
aContext->DefaultDrawer()->ShadingAspect()->Aspect()->PolygonOffsets(aMode, aFactor, aUnits);
std::cout << "\tMode: " << aMode << '\n';
std::cout << "\tFactor: " << aFactor << '\n';
std::cout << "\tUnits: " << aUnits << '\n';
return 0;
}
// This class is used for testing markers.
class ViewerTest_MarkersArrayObject : public AIS_InteractiveObject
{
public:
ViewerTest_MarkersArrayObject(const gp_XYZ& theStartPoint,
const int& thePointsOnSide,
occ::handle<Graphic3d_AspectMarker3d> theMarkerAspect = nullptr)
{
myStartPoint = theStartPoint;
myPointsOnSide = thePointsOnSide;
myMarkerAspect = std::move(theMarkerAspect);
}
DEFINE_STANDARD_RTTI_INLINE(ViewerTest_MarkersArrayObject, AIS_InteractiveObject);
private:
void Compute(const occ::handle<PrsMgr_PresentationManager>& thePrsMgr,
const occ::handle<Prs3d_Presentation>& thePrs,
const int theMode) override;
void ComputeSelection(const occ::handle<SelectMgr_Selection>& theSel, const int theMode) override;
protected:
gp_XYZ myStartPoint;
int myPointsOnSide;
occ::handle<Graphic3d_AspectMarker3d> myMarkerAspect;
};
void ViewerTest_MarkersArrayObject::Compute(const occ::handle<PrsMgr_PresentationManager>&,
const occ::handle<Prs3d_Presentation>& aPresentation,
const int)
{
occ::handle<Graphic3d_ArrayOfPrimitives> anArray =
new Graphic3d_ArrayOfPoints((int)std::pow(myPointsOnSide, 3), myPointsOnSide != 1);
if (myPointsOnSide == 1)
{
anArray->AddVertex(myStartPoint);
}
else
{
for (double i = 1; i <= myPointsOnSide; i++)
{
for (double j = 1; j <= myPointsOnSide; j++)
{
for (double k = 1; k <= myPointsOnSide; k++)
{
anArray->AddVertex(myStartPoint.X() + i, myStartPoint.Y() + j, myStartPoint.Z() + k);
anArray->SetVertexColor(anArray->VertexNumber(),
i / myPointsOnSide,
j / myPointsOnSide,
k / myPointsOnSide);
}
}
}
}
aPresentation->Clear();
if (!myMarkerAspect.IsNull())
{
aPresentation->CurrentGroup()->SetGroupPrimitivesAspect(myMarkerAspect);
}
aPresentation->CurrentGroup()->AddPrimitiveArray(anArray);
}
void ViewerTest_MarkersArrayObject::ComputeSelection(
const occ::handle<SelectMgr_Selection>& theSelection,
const int /*theMode*/)
{
occ::handle<SelectMgr_EntityOwner> anEntityOwner = new SelectMgr_EntityOwner(this);
if (myPointsOnSide == 1)
{
gp_Pnt aPoint(myStartPoint);
occ::handle<Select3D_SensitivePoint> aSensetivePoint =
new Select3D_SensitivePoint(anEntityOwner, aPoint);
theSelection->Add(aSensetivePoint);
}
else
{
for (double i = 1; i <= myPointsOnSide; i++)
{
for (double j = 1; j <= myPointsOnSide; j++)
{
for (double k = 1; k <= myPointsOnSide; k++)
{
gp_Pnt aPoint(myStartPoint.X() + i, myStartPoint.Y() + j, myStartPoint.Z() + k);
occ::handle<Select3D_SensitivePoint> aSensetivePoint =
new Select3D_SensitivePoint(anEntityOwner, aPoint);
theSelection->Add(aSensetivePoint);
}
}
}
}
}
//=======================================================================
// function : VMarkersTest
// purpose : Draws an array of markers for testing purposes.
//=======================================================================
static int VMarkersTest(Draw_Interpretor&, int theArgNb, const char** theArgVec)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
if (theArgNb < 5)
{
Message::SendFail("Syntax error: wrong number of arguments");
return 1;
}
int anArgIter = 1;
TCollection_AsciiString aName(theArgVec[anArgIter++]);
TCollection_AsciiString aFileName;
gp_XYZ aPnt(Atof(theArgVec[anArgIter]),
Atof(theArgVec[anArgIter + 1]),
Atof(theArgVec[anArgIter + 2]));
anArgIter += 3;
int aPointsOnSide = 10;
int aMarkerType = -1;
double aScale = 1.0;
for (; anArgIter < theArgNb; ++anArgIter)
{
const TCollection_AsciiString anArg(theArgVec[anArgIter]);
if (anArg.Search("PointsOnSide=") > -1)
{
aPointsOnSide = anArg.Token("=", 2).IntegerValue();
}
else if (anArg.Search("MarkerType=") > -1)
{
aMarkerType = anArg.Token("=", 2).IntegerValue();
}
else if (anArg.Search("Scale=") > -1)
{
aScale = anArg.Token("=", 2).RealValue();
}
else if (anArg.Search("FileName=") > -1)
{
aFileName = anArg.Token("=", 2);
}
else
{
Message::SendFail() << "Syntax error: wrong argument '" << anArg << "'";
return 1;
}
}
occ::handle<Graphic3d_AspectMarker3d> anAspect;
occ::handle<Image_AlienPixMap> anImage;
Quantity_Color aColor(Quantity_NOC_GREEN1);
if ((aMarkerType == Aspect_TOM_USERDEFINED || aMarkerType < 0) && !aFileName.IsEmpty())
{
anImage = new Image_AlienPixMap();
if (!anImage->Load(aFileName))
{
Message::SendFail() << "Error: could not load image from file '" << aFileName << "'!";
return 1;
}
if (anImage->Format() == Image_Format_Gray)
{
anImage->SetFormat(Image_Format_Alpha);
}
else if (anImage->Format() == Image_Format_GrayF)
{
anImage->SetFormat(Image_Format_AlphaF);
}
anAspect = new Graphic3d_AspectMarker3d(anImage);
}
else
{
anAspect = new Graphic3d_AspectMarker3d(aMarkerType >= 0 ? (Aspect_TypeOfMarker)aMarkerType
: Aspect_TOM_POINT,
aColor,
aScale);
}
occ::handle<ViewerTest_MarkersArrayObject> aMarkersArray =
new ViewerTest_MarkersArrayObject(aPnt, aPointsOnSide, anAspect);
VDisplayAISObject(aName, aMarkersArray);
return 0;
}
//=======================================================================
// function : TextToBrep
// purpose : Tool for conversion text to occt-shapes
//=======================================================================
static int TextToBRep(Draw_Interpretor& /*theDI*/, int theArgNb, const char** theArgVec)
{
// Check arguments
if (theArgNb < 3)
{
Message::SendFail() << "Error: " << theArgVec[0] << " - invalid syntax";
return 1;
}
int anArgIt = 1;
const char* aName = theArgVec[anArgIt++];
const char* aText = theArgVec[anArgIt++];
StdPrs_BRepFont aFont;
TCollection_AsciiString aFontName("Courier");
double aTextHeight = 16.0;
Font_FontAspect aFontAspect = Font_FA_Regular;
bool toConcatenateContours = false;
gp_Ax3 aPenAx3(gp::XOY());
gp_Dir aNormal(gp_Dir::D::Z);
gp_Dir aDirection(gp_Dir::D::X);
gp_Pnt aPenLoc;
Graphic3d_HorizontalTextAlignment aHJustification = Graphic3d_HTA_LEFT;
Graphic3d_VerticalTextAlignment aVJustification = Graphic3d_VTA_BOTTOM;
Font_StrictLevel aStrictLevel = Font_StrictLevel_Any;
for (; anArgIt < theArgNb; ++anArgIt)
{
TCollection_AsciiString aParam(theArgVec[anArgIt]);
aParam.LowerCase();
if (aParam == "-pos" || aParam == "-position")
{
if (anArgIt + 3 >= theArgNb)
{
Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
return 1;
}
aPenLoc.SetX(Draw::Atof(theArgVec[++anArgIt]));
aPenLoc.SetY(Draw::Atof(theArgVec[++anArgIt]));
aPenLoc.SetZ(Draw::Atof(theArgVec[++anArgIt]));
}
else if (aParam == "-halign")
{
if (++anArgIt >= theArgNb)
{
Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
return 1;
}
TCollection_AsciiString aType(theArgVec[anArgIt]);
aType.LowerCase();
if (aType == "left")
{
aHJustification = Graphic3d_HTA_LEFT;
}
else if (aType == "center")
{
aHJustification = Graphic3d_HTA_CENTER;
}
else if (aType == "right")
{
aHJustification = Graphic3d_HTA_RIGHT;
}
else
{
Message::SendFail() << "Error: wrong syntax at '" << aParam << "'";
return 1;
}
}
else if (aParam == "-valign")
{
if (++anArgIt >= theArgNb)
{
Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
return 1;
}
TCollection_AsciiString aType(theArgVec[anArgIt]);
aType.LowerCase();
if (aType == "top")
{
aVJustification = Graphic3d_VTA_TOP;
}
else if (aType == "center")
{
aVJustification = Graphic3d_VTA_CENTER;
}
else if (aType == "bottom")
{
aVJustification = Graphic3d_VTA_BOTTOM;
}
else if (aType == "topfirstline")
{
aVJustification = Graphic3d_VTA_TOPFIRSTLINE;
}
else
{
Message::SendFail() << "Error: wrong syntax at '" << aParam << "'";
return 1;
}
}
else if (aParam == "-height")
{
if (++anArgIt >= theArgNb)
{
Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
return 1;
}
aTextHeight = Draw::Atof(theArgVec[anArgIt]);
}
else if (aParam == "-aspect")
{
if (++anArgIt >= theArgNb)
{
Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
return 1;
}
TCollection_AsciiString anOption(theArgVec[anArgIt]);
anOption.LowerCase();
if (!parseFontStyle(anOption, aFontAspect))
{
Message::SendFail() << "Error: unknown font aspect '" << anOption << "'";
return 1;
}
}
else if (aParam == "-font")
{
if (++anArgIt >= theArgNb)
{
Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
return 1;
}
aFontName = theArgVec[anArgIt];
}
else if (aParam == "-strict")
{
anArgIt +=
parseFontStrictLevel(theArgNb - anArgIt - 1, theArgVec + anArgIt + 1, aStrictLevel);
}
else if (aParam == "-composite")
{
if (++anArgIt >= theArgNb)
{
Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
return 1;
}
Draw::ParseOnOff(theArgVec[anArgIt], toConcatenateContours);
}
else if (aParam == "-plane")
{
if (anArgIt + 6 >= theArgNb)
{
Message::SendFail() << "Error: wrong number of values for parameter '" << aParam << "'";
return 1;
}
double aX = Draw::Atof(theArgVec[++anArgIt]);
double aY = Draw::Atof(theArgVec[++anArgIt]);
double aZ = Draw::Atof(theArgVec[++anArgIt]);
aNormal.SetCoord(aX, aY, aZ);
aX = Draw::Atof(theArgVec[++anArgIt]);
aY = Draw::Atof(theArgVec[++anArgIt]);
aZ = Draw::Atof(theArgVec[++anArgIt]);
aDirection.SetCoord(aX, aY, aZ);
}
else
{
Message::SendFail() << "Warning! Unknown argument '" << aParam << "'";
}
}
if (!aFont.FindAndInit(aFontName.ToCString(), aFontAspect, aTextHeight, aStrictLevel))
{
Message::SendFail("Error: unable to load Font");
return 1;
}
aPenAx3 = gp_Ax3(aPenLoc, aNormal, aDirection);
StdPrs_BRepFont::TextOptions anOptions;
anOptions.Pen = aPenAx3;
anOptions.HorizontalAlignment = aHJustification;
anOptions.VerticalAlignment = aVJustification;
anOptions.ToConcatenateContours = toConcatenateContours;
const TopoDS_Shape aResult = aFont.RenderText(aText, anOptions);
if (aResult.IsNull())
{
Message::SendFail("Error: unable to create text shape");
return 1;
}
DBRep::Set(aName, aResult);
return 0;
}
//=================================================================================================
struct FontComparator
{
bool operator()(const occ::handle<Font_SystemFont>& theFontA,
const occ::handle<Font_SystemFont>& theFontB)
{
return theFontA->FontKey().IsLess(theFontB->FontKey());
}
};
static int VFont(Draw_Interpretor& theDI, int theArgNb, const char** theArgVec)
{
occ::handle<Font_FontMgr> aMgr = Font_FontMgr::GetInstance();
bool toPrintList = theArgNb < 2, toPrintNames = false;
Font_StrictLevel aStrictLevel = Font_StrictLevel_Any;
for (int anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
{
const TCollection_AsciiString anArg(theArgVec[anArgIter]);
TCollection_AsciiString anArgCase(anArg);
anArgCase.LowerCase();
if (anArgCase == "-strict")
{
anArgIter +=
parseFontStrictLevel(theArgNb - anArgIter - 1, theArgVec + anArgIter + 1, aStrictLevel);
}
else if (anArgCase == "-clear")
{
aMgr->ClearFontDataBase();
}
else if (anArgCase == "-init")
{
aMgr->InitFontDataBase();
}
else if (anArgCase == "-list")
{
toPrintList = true;
}
else if (anArgCase == "-names")
{
toPrintList = true;
toPrintNames = true;
}
else if (anArgIter + 1 < theArgNb
&& (anArgCase == "-find" || anArgCase == "-findinfo" || anArgCase == "-findall"
|| anArgCase == "find"))
{
const TCollection_AsciiString aFontName(theArgVec[++anArgIter]);
Font_FontAspect aFontAspect = Font_FA_Undefined;
if (++anArgIter < theArgNb)
{
anArgCase = theArgVec[anArgIter];
anArgCase.LowerCase();
if (!parseFontStyle(anArgCase, aFontAspect))
{
--anArgIter;
}
}
const bool toFindAll = (anArgCase == "-findall");
const bool toPrintInfo = (anArgCase == "-findinfo");
TCollection_AsciiString aResult;
if (toFindAll || aFontName.Search("*") != -1)
{
const NCollection_List<occ::handle<Font_SystemFont>> aFonts = aMgr->GetAvailableFonts();
NCollection_LinearVector<occ::handle<Font_SystemFont>> aFontsSorted;
aFontsSorted.Reserve(aFonts.Size());
for (NCollection_List<occ::handle<Font_SystemFont>>::Iterator aFontIter(aFonts);
aFontIter.More();
aFontIter.Next())
{
aFontsSorted.Append(aFontIter.Value());
}
std::stable_sort(aFontsSorted.begin(), aFontsSorted.end(), FontComparator());
for (const occ::handle<Font_SystemFont>& aFont : aFontsSorted)
{
const TCollection_AsciiString aCheck = TCollection_AsciiString("string match -nocase \"")
+ aFontName + "\" \"" + aFont->FontName() + "\"";
if (theDI.Eval(aCheck.ToCString()) == 0 && *theDI.Result() != '1')
{
theDI.Reset();
continue;
}
theDI.Reset();
if (!aResult.IsEmpty())
{
aResult += "\n";
}
aResult += toPrintInfo ? aFont->ToString() : aFont->FontName();
if (!toFindAll)
{
break;
}
}
}
else if (occ::handle<Font_SystemFont> aFont =
aMgr->FindFont(aFontName, aStrictLevel, aFontAspect))
{
aResult = toPrintInfo ? aFont->ToString() : aFont->FontName();
}
if (!aResult.IsEmpty())
{
theDI << aResult;
}
else
{
Message::SendFail() << "Error: font '" << aFontName << "' is not found";
}
}
else if (anArgIter + 1 < theArgNb
&& (anArgCase == "-add" || anArgCase == "add" || anArgCase == "-register"
|| anArgCase == "register"))
{
++anArgIter;
const char* aFontPath = theArgVec[anArgIter++];
TCollection_AsciiString aFontName;
Font_FontAspect aFontAspect = Font_FA_Undefined;
int isSingelStroke = -1;
for (; anArgIter < theArgNb; ++anArgIter)
{
anArgCase = theArgVec[anArgIter];
anArgCase.LowerCase();
if (aFontAspect == Font_FontAspect_UNDEFINED && parseFontStyle(anArgCase, aFontAspect))
{
continue;
}
else if (anArgCase == "singlestroke" || anArgCase == "singleline" || anArgCase == "oneline")
{
isSingelStroke = 1;
}
else if (aFontName.IsEmpty())
{
aFontName = theArgVec[anArgIter];
}
else
{
--anArgIter;
break;
}
}
occ::handle<Font_SystemFont> aFont = aMgr->CheckFont(aFontPath);
if (aFont.IsNull())
{
Message::SendFail() << "Error: font '" << aFontPath << "' is not found!";
continue;
}
if (aFontAspect != Font_FontAspect_UNDEFINED || !aFontName.IsEmpty())
{
TCollection_AsciiString aName = aFont->FontName();
if (!aFontName.IsEmpty())
{
aName = aFontName;
}
occ::handle<Font_SystemFont> aFont2 = new Font_SystemFont(aName);
if (aFontAspect != Font_FontAspect_UNDEFINED)
{
aFont2->SetFontPath(aFontAspect, aFontPath, 0);
}
else
{
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
{
aFont2->SetFontPath((Font_FontAspect)anAspectIter,
aFont->FontPath((Font_FontAspect)anAspectIter),
aFont->FontFaceId((Font_FontAspect)anAspectIter));
}
}
aFont = aFont2;
}
if (isSingelStroke != -1)
{
aFont->SetSingleStrokeFont(isSingelStroke == 1);
}
aMgr->RegisterFont(aFont, true);
theDI << aFont->ToString();
}
else if (anArgCase == "-aliases")
{
TCollection_AsciiString anAliasName;
NCollection_Sequence<occ::handle<TCollection_HAsciiString>> aNames;
if (anArgIter + 1 < theArgNb && *theArgVec[anArgIter + 1] != '-')
{
anAliasName = theArgVec[++anArgIter];
}
if (!anAliasName.IsEmpty())
{
aMgr->GetFontAliases(aNames, anAliasName);
}
else
{
aMgr->GetAllAliases(aNames);
}
for (NCollection_Sequence<occ::handle<TCollection_HAsciiString>>::Iterator aNameIter(aNames);
aNameIter.More();
aNameIter.Next())
{
theDI << "{" << aNameIter.Value()->String() << "} ";
}
}
else if (anArgIter + 2 < theArgNb && anArgCase == "-addalias")
{
TCollection_AsciiString anAliasName(theArgVec[++anArgIter]);
TCollection_AsciiString aFontName(theArgVec[++anArgIter]);
aMgr->AddFontAlias(anAliasName, aFontName);
}
else if (anArgIter + 2 < theArgNb && anArgCase == "-removealias")
{
TCollection_AsciiString anAliasName(theArgVec[++anArgIter]);
TCollection_AsciiString aFontName(theArgVec[++anArgIter]);
aMgr->RemoveFontAlias(anAliasName, aFontName);
}
else if (anArgIter + 1 < theArgNb && anArgCase == "-clearalias")
{
TCollection_AsciiString anAliasName(theArgVec[++anArgIter]);
aMgr->RemoveFontAlias(anAliasName, "");
}
else if (anArgCase == "-clearaliases")
{
aMgr->RemoveFontAlias("", "");
}
else if (anArgCase == "-verbose" || anArgCase == "-trace")
{
bool toEnable = true;
if (anArgIter + 1 < theArgNb && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
{
++anArgIter;
}
aMgr->SetTraceAliases(toEnable);
}
else if (anArgCase == "-unicodefallback" || anArgCase == "-fallback"
|| anArgCase == "-touseunicodesubsetfallback")
{
bool toEnable = true;
if (anArgIter + 1 < theArgNb && Draw::ParseOnOff(theArgVec[anArgIter + 1], toEnable))
{
++anArgIter;
}
Font_FontMgr::SetUseUnicodeSubsetFallback(toEnable);
}
else
{
Message::SendFail() << "Warning! Unknown argument '" << anArg << "'";
}
}
if (toPrintList)
{
// just print the list of available fonts
bool isFirst = true;
const NCollection_List<occ::handle<Font_SystemFont>> aFonts = aMgr->GetAvailableFonts();
NCollection_LinearVector<occ::handle<Font_SystemFont>> aFontsSorted;
aFontsSorted.Reserve(aFonts.Size());
for (NCollection_List<occ::handle<Font_SystemFont>>::Iterator aFontIter(aFonts);
aFontIter.More();
aFontIter.Next())
{
aFontsSorted.Append(aFontIter.Value());
}
std::stable_sort(aFontsSorted.begin(), aFontsSorted.end(), FontComparator());
for (const occ::handle<Font_SystemFont>& aFont : aFontsSorted)
{
if (toPrintNames)
{
if (!isFirst)
{
theDI << "\n";
}
theDI << "\"" << aFont->FontName() << "\"";
}
else
{
if (!isFirst)
{
theDI << "\n";
}
theDI << aFont->ToString();
}
isFirst = false;
}
}
return 0;
}
//=======================================================================
// function : VVertexMode
// purpose : Switches vertex display mode for AIS_Shape or displays the current value
//=======================================================================
static int VVertexMode(Draw_Interpretor& theDI, int theArgNum, const char** theArgs)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
// No arguments --> print the current default vertex draw mode
if (theArgNum == 1)
{
Prs3d_VertexDrawMode aCurrMode = aContext->DefaultDrawer()->VertexDrawMode();
theDI << "Default vertex draw mode: "
<< (aCurrMode == Prs3d_VDM_Isolated ? "'isolated'" : "'all'") << "\n";
return 0;
}
// -set argument --> change the default vertex draw mode and the mode for all displayed or given
// object(s)
TCollection_AsciiString aParam(theArgs[1]);
if (aParam == "-set")
{
if (theArgNum == 2)
{
Message::SendFail(
"Error: '-set' option not followed by the mode and optional object name(s)\n"
"Type 'help vvertexmode' for usage hints");
return 1;
}
TCollection_AsciiString aModeStr(theArgs[2]);
Prs3d_VertexDrawMode aNewMode = aModeStr == "isolated"
? Prs3d_VDM_Isolated
: (aModeStr == "all" ? Prs3d_VDM_All : Prs3d_VDM_Inherited);
bool aRedrawNeeded = false;
NCollection_List<occ::handle<AIS_InteractiveObject>> anObjs;
// No object(s) specified -> use all displayed
if (theArgNum == 3)
{
theDI << "Setting the default vertex draw mode and updating all displayed objects...\n";
aContext->DisplayedObjects(anObjs);
aContext->DefaultDrawer()->SetVertexDrawMode(aNewMode);
aRedrawNeeded = true;
}
occ::handle<AIS_InteractiveObject> anObject;
for (int aCount = 3; aCount < theArgNum; aCount++)
{
TCollection_AsciiString aName(theArgs[aCount]);
if (!GetMapOfAIS().Find2(aName, anObject))
{
theDI << "Warning: wrong object name ignored - " << theArgs[0] << "\n";
continue;
}
anObjs.Append(anObject);
}
for (NCollection_List<occ::handle<AIS_InteractiveObject>>::Iterator anIt(anObjs); anIt.More();
anIt.Next())
{
anObject = anIt.Value();
anObject->Attributes()->SetVertexDrawMode(aNewMode);
aContext->Redisplay(anObject, false);
aRedrawNeeded = true;
}
if (aRedrawNeeded)
{
ViewerTest::CurrentView()->Redraw();
}
return 0;
}
occ::handle<AIS_InteractiveObject> anObject;
if (theArgNum > 2 || !GetMapOfAIS().Find2(aParam, anObject))
{
Message::SendFail("Syntax error: invalid number of arguments");
return 1;
}
// One argument (object name) --> print the current vertex draw mode for the object
Prs3d_VertexDrawMode aCurrMode = anObject->Attributes()->VertexDrawMode();
theDI << "Object's vertex draw mode: "
<< (aCurrMode == Prs3d_VDM_Isolated ? "'isolated'" : "'all'") << "\n";
return 0;
}
//=======================================================================
// function : VPointCloud
// purpose : Create interactive object for arbitrary set of points.
//=======================================================================
static int VPointCloud(Draw_Interpretor& theDI, int theArgNum, const char** theArgs)
{
if (theArgNum < 2)
{
Message::SendFail("Syntax error: wrong number of arguments");
return 1;
}
occ::handle<AIS_InteractiveContext> anAISContext = ViewerTest::GetAISContext();
if (anAISContext.IsNull())
{
Message::SendFail("Error: no active view!");
return 1;
}
TCollection_AsciiString aName;
TopoDS_Shape aShape;
TCollection_AsciiString aDistribution;
gp_Pnt aDistCenter;
double aDistRadius = 0.0;
int aDistNbPoints = 0;
// parse options
bool toRandColors = false;
bool hasNormals = true, hasUV = false;
bool isDensityPoints = false;
double aDensity = 0.0, aDist = 0.0;
double aTol = Precision::Confusion();
for (int anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
{
TCollection_AsciiString aFlag(theArgs[anArgIter]);
aFlag.LowerCase();
if (aFlag == "-randcolors" || aFlag == "-randcolor")
{
toRandColors = Draw::ParseOnOffIterator(theArgNum, theArgs, anArgIter);
}
else if (aFlag == "-normals" || aFlag == "-normal")
{
hasNormals = Draw::ParseOnOffIterator(theArgNum, theArgs, anArgIter);
}
else if (aFlag == "-nonormals" || aFlag == "-nonormal")
{
hasNormals = !Draw::ParseOnOffIterator(theArgNum, theArgs, anArgIter);
}
else if (aFlag == "-uv" || aFlag == "-texels")
{
hasUV = Draw::ParseOnOffIterator(theArgNum, theArgs, anArgIter);
}
else if ((aFlag == "-dist" || aFlag == "-distance") && anArgIter + 1 < theArgNum
&& Draw::ParseReal(theArgs[anArgIter + 1], aDist))
{
++anArgIter;
if (aDist < 0.0)
{
theDI << "Syntax error: -distance value should be >= 0.0";
return 1;
}
aDist = std::max(aDist, Precision::Confusion());
}
else if ((aFlag == "-dens" || aFlag == "-density") && anArgIter + 1 < theArgNum
&& Draw::ParseReal(theArgs[anArgIter + 1], aDensity))
{
++anArgIter;
isDensityPoints = true;
if (aDensity <= 0.0)
{
theDI << "Syntax error: -density value should be > 0.0";
return 1;
}
}
else if ((aFlag == "-tol" || aFlag == "-tolerance") && anArgIter + 1 < theArgNum
&& Draw::ParseReal(theArgs[anArgIter + 1], aTol))
{
++anArgIter;
if (aTol < Precision::Confusion())
{
theDI << "Syntax error: -tol value should be >= " << Precision::Confusion();
return 1;
}
}
else if ((aFlag == "-surface" || aFlag == "-volume") && anArgIter + 5 < theArgNum)
{
aDistribution = aFlag;
aDistCenter.SetCoord(Draw::Atof(theArgs[anArgIter + 1]),
Draw::Atof(theArgs[anArgIter + 2]),
Draw::Atof(theArgs[anArgIter + 3]));
aDistRadius = Draw::Atof(theArgs[anArgIter + 4]);
aDistNbPoints = Draw::Atoi(theArgs[anArgIter + 5]);
anArgIter += 5;
}
else if (aName.IsEmpty())
{
aName = theArgs[anArgIter];
}
else if (aShape.IsNull())
{
aShape = DBRep::Get(theArgs[anArgIter]);
if (aShape.IsNull())
{
theDI << "Syntax error: invalid shape '" << theArgs[anArgIter] << "'";
return 1;
}
}
else
{
theDI << "Syntax error at '" << theArgs[anArgIter] << "'";
return 1;
}
}
Graphic3d_ArrayFlags aFlags = Graphic3d_ArrayFlags_None;
if (hasNormals)
{
aFlags |= Graphic3d_ArrayFlags_VertexNormal;
}
if (toRandColors)
{
aFlags |= Graphic3d_ArrayFlags_VertexColor;
}
if (hasUV)
{
aFlags |= Graphic3d_ArrayFlags_VertexTexel;
}
// generate arbitrary set of points
occ::handle<Graphic3d_ArrayOfPoints> anArrayPoints;
if (!aShape.IsNull())
{
class PointCloudPntFiller : public BRepLib_PointCloudShape
{
public:
PointCloudPntFiller(double theTol)
: BRepLib_PointCloudShape(TopoDS_Shape(), theTol)
{
}
void SetPointArray(const occ::handle<Graphic3d_ArrayOfPoints>& thePoints)
{
myPoints = thePoints;
}
protected:
void addPoint(const gp_Pnt& thePoint,
const gp_Vec& theNorm,
const gp_Pnt2d& theUV,
const TopoDS_Shape&) override
{
const int aPntIndex = myPoints->AddVertex(thePoint, theUV);
if (theNorm.SquareMagnitude() > gp::Resolution())
{
myPoints->SetVertexNormal(aPntIndex, theNorm);
}
if (myPoints->HasVertexColors())
{
Quantity_Color aColor(360.0 * double(aPntIndex)
/ double(myPoints->VertexNumberAllocated()),
1.0,
0.5,
Quantity_TOC_HLS);
myPoints->SetVertexColor(aPntIndex, aColor);
}
}
private:
occ::handle<Graphic3d_ArrayOfPoints> myPoints;
};
PointCloudPntFiller aPoitCloudTool(aTol);
aPoitCloudTool.SetShape(aShape);
aPoitCloudTool.SetDistance(aDist);
int aNbPoints = isDensityPoints ? aPoitCloudTool.NbPointsByDensity(aDensity)
: aPoitCloudTool.NbPointsByTriangulation();
theDI << "Number of the generated points : " << aNbPoints << "\n";
anArrayPoints = new Graphic3d_ArrayOfPoints(aNbPoints, aFlags);
aPoitCloudTool.SetPointArray(anArrayPoints);
bool isDone = isDensityPoints ? aPoitCloudTool.GeneratePointsByDensity(aDensity)
: aPoitCloudTool.GeneratePointsByTriangulation();
if (!isDone)
{
Message::SendFail() << "Error: Point cloud was not generated";
return 1;
}
}
else if (!aDistribution.IsEmpty())
{
const bool isSurface = aDistribution == "-surface";
anArrayPoints = new Graphic3d_ArrayOfPoints(aDistNbPoints, aFlags);
std::mt19937 aRandomGenerator(0);
std::uniform_real_distribution<> anAlphaDistrib(0.0, 2.0 * M_PI);
std::uniform_real_distribution<> aBetaDistrib(0.0, 2.0 * M_PI);
std::uniform_real_distribution<> aRadiusDistrib(0.0, aDistRadius);
for (int aPntIt = 0; aPntIt < aDistNbPoints; ++aPntIt)
{
double anAlpha = anAlphaDistrib(aRandomGenerator);
double aBeta = aBetaDistrib(aRandomGenerator);
double aDistance = isSurface ? aDistRadius : aRadiusDistrib(aRandomGenerator);
gp_Dir aDir(std::cos(anAlpha) * std::sin(aBeta),
std::sin(anAlpha),
std::cos(anAlpha) * std::cos(aBeta));
gp_Pnt aPoint = aDistCenter.Translated(aDir.XYZ() * aDistance);
const int anIndexOfPoint = anArrayPoints->AddVertex(aPoint);
if (toRandColors)
{
Quantity_Color aColor(360.0 * double(anIndexOfPoint) / double(aDistNbPoints),
1.0,
0.5,
Quantity_TOC_HLS);
anArrayPoints->SetVertexColor(anIndexOfPoint, aColor);
}
if (hasNormals)
{
anArrayPoints->SetVertexNormal(anIndexOfPoint, aDir);
}
if (hasUV)
{
anArrayPoints->SetVertexTexel(anIndexOfPoint,
gp_Pnt2d(anAlpha / 2.0 * M_PI, aBeta / 2.0 * M_PI));
}
}
}
else
{
Message::SendFail("Error: wrong number of arguments");
return 1;
}
// set array of points in point cloud object
occ::handle<AIS_PointCloud> aPointCloud = new AIS_PointCloud();
aPointCloud->SetPoints(anArrayPoints);
ViewerTest::Display(aName, aPointCloud);
return 0;
}
//=======================================================================
// function : VPriority
// purpose : Prints or sets the display priority for an object
//=======================================================================
static int VPriority(Draw_Interpretor& theDI, int theArgNum, const char** theArgs)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
TCollection_AsciiString aLastArg(theArgs[theArgNum - 1]);
int aPriority = Graphic3d_DisplayPriority_INVALID;
int aNbArgs = theArgNum;
if (aLastArg.IsIntegerValue())
{
aPriority = aLastArg.IntegerValue();
--aNbArgs;
if (aPriority < Graphic3d_DisplayPriority_Bottom
|| aPriority > Graphic3d_DisplayPriority_Topmost)
{
Message::SendFail() << "Syntax error: the specified display priority value '" << aLastArg
<< "' is outside the valid range [" << Graphic3d_DisplayPriority_Bottom
<< ".." << Graphic3d_DisplayPriority_Topmost << "]";
return 1;
}
}
else
{
anUpdateTool.Invalidate();
}
if (aNbArgs < 2)
{
Message::SendFail("Syntax error: wrong number of arguments! See usage:");
theDI.PrintHelp(theArgs[0]);
return 1;
}
for (int anArgIter = 1; anArgIter < aNbArgs; ++anArgIter)
{
if (anUpdateTool.parseRedrawMode(theArgs[anArgIter]))
{
continue;
}
TCollection_AsciiString aName(theArgs[anArgIter]);
occ::handle<AIS_InteractiveObject> anIObj;
GetMapOfAIS().Find2(aName, anIObj);
if (anIObj.IsNull())
{
Message::SendFail() << "Error: the object '" << theArgs[1] << "' is not displayed";
return 1;
}
if (aPriority == Graphic3d_DisplayPriority_INVALID)
{
theDI << aContext->DisplayPriority(anIObj) << " ";
}
else
{
aContext->SetDisplayPriority(anIObj, (Graphic3d_DisplayPriority)aPriority);
}
}
return 0;
}
//! Auxiliary class for command vnormals.
class MyShapeWithNormals : public AIS_Shape
{
DEFINE_STANDARD_RTTI_INLINE(MyShapeWithNormals, AIS_Shape);
public:
double NormalLength;
int NbAlongU;
int NbAlongV;
bool ToUseMesh;
bool ToOrient;
public:
//! Main constructor.
MyShapeWithNormals(const TopoDS_Shape& theShape)
: AIS_Shape(theShape),
NormalLength(10),
NbAlongU(1),
NbAlongV(1),
ToUseMesh(false),
ToOrient(false)
{
}
protected:
//! Compute presentation.
void Compute(const occ::handle<PrsMgr_PresentationManager>& thePrsMgr,
const occ::handle<Prs3d_Presentation>& thePrs,
const int theMode) override
{
AIS_Shape::Compute(thePrsMgr, thePrs, theMode);
NCollection_DataMap<TopoDS_Face, NCollection_DynamicArray<std::pair<gp_Pnt, gp_Pnt>>>
aNormalMap;
if (ToUseMesh)
{
DBRep_DrawableShape::addMeshNormals(aNormalMap, myshape, NormalLength);
}
else
{
DBRep_DrawableShape::addSurfaceNormals(aNormalMap, myshape, NormalLength, NbAlongU, NbAlongV);
}
occ::handle<Graphic3d_Group> aPrsGroup = thePrs->NewGroup();
aPrsGroup->SetGroupPrimitivesAspect(myDrawer->ArrowAspect()->Aspect());
const double aArrowAngle = myDrawer->ArrowAspect()->Angle();
const double aArrowLength = myDrawer->ArrowAspect()->Length();
for (NCollection_DataMap<TopoDS_Face,
NCollection_DynamicArray<std::pair<gp_Pnt, gp_Pnt>>>::Iterator
aFaceIt(aNormalMap);
aFaceIt.More();
aFaceIt.Next())
{
const bool toReverse = ToOrient && aFaceIt.Key().Orientation() == TopAbs_REVERSED;
occ::handle<Graphic3d_ArrayOfSegments> aSegments =
new Graphic3d_ArrayOfSegments(2 * aFaceIt.Value().Length());
for (NCollection_DynamicArray<std::pair<gp_Pnt, gp_Pnt>>::Iterator aPntIt(aFaceIt.Value());
aPntIt.More();
aPntIt.Next())
{
std::pair<gp_Pnt, gp_Pnt> aPair = aPntIt.Value();
if (toReverse)
{
const gp_Vec aDir = aPair.first.XYZ() - aPair.second.XYZ();
aPair.second = aPair.first.XYZ() + aDir.XYZ();
}
aSegments->AddVertex(aPair.first);
aSegments->AddVertex(aPair.second);
Prs3d_Arrow::Draw(aPrsGroup,
aPair.second,
gp_Vec(aPair.first, aPair.second),
aArrowAngle,
aArrowLength);
}
aPrsGroup->AddPrimitiveArray(aSegments);
}
}
};
//=======================================================================
// function : VNormals
// purpose : Displays/Hides normals calculated on shape geometry or retrieved from triangulation
//=======================================================================
static int VNormals(Draw_Interpretor& theDI, int theArgNum, const char** theArgs)
{
occ::handle<AIS_InteractiveContext> aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
Message::SendFail("Error: no active viewer");
return 1;
}
else if (theArgNum < 2)
{
Message::SendFail("Syntax error: wrong number of arguments. See usage:");
theDI.PrintHelp(theArgs[0]);
return 1;
}
int anArgIter = 1;
const char* aShapeName = theArgs[anArgIter++];
TopoDS_Shape aShape = DBRep::Get(aShapeName);
bool isOn = true;
if (aShape.IsNull())
{
Message::SendFail() << "Error: shape with name '" << aShapeName << "' is not found";
return 1;
}
NCollection_DoubleMap<occ::handle<AIS_InteractiveObject>, TCollection_AsciiString>& aMap =
GetMapOfAIS();
occ::handle<MyShapeWithNormals> aShapePrs;
if (aMap.IsBound2(aShapeName))
{
aShapePrs = occ::down_cast<MyShapeWithNormals>(aMap.Find2(aShapeName));
}
bool isUseMesh = false;
double aLength = 10.0;
int aNbAlongU = 1, aNbAlongV = 1;
bool isOriented = false;
for (; anArgIter < theArgNum; ++anArgIter)
{
TCollection_AsciiString aParam(theArgs[anArgIter]);
aParam.LowerCase();
if (anArgIter == 2 && Draw::ParseOnOff(aParam.ToCString(), isOn))
{
continue;
}
else if (aParam == "-usemesh" || aParam == "-mesh")
{
isUseMesh = true;
}
else if (aParam == "-length" || aParam == "-len")
{
++anArgIter;
aLength = anArgIter < theArgNum ? Draw::Atof(theArgs[anArgIter]) : 0.0;
if (std::abs(aLength) <= gp::Resolution())
{
Message::SendFail("Syntax error: length should not be zero");
return 1;
}
}
else if (aParam == "-orient" || aParam == "-oriented")
{
isOriented = true;
if (anArgIter + 1 < theArgNum && Draw::ParseOnOff(theArgs[anArgIter + 1], isOriented))
{
++anArgIter;
}
}
else if (aParam == "-nbalongu" || aParam == "-nbu")
{
++anArgIter;
aNbAlongU = anArgIter < theArgNum ? Draw::Atoi(theArgs[anArgIter]) : 0;
if (aNbAlongU < 1)
{
Message::SendFail("Syntax error: NbAlongU should be >=1");
return 1;
}
}
else if (aParam == "-nbalongv" || aParam == "-nbv")
{
++anArgIter;
aNbAlongV = anArgIter < theArgNum ? Draw::Atoi(theArgs[anArgIter]) : 0;
if (aNbAlongV < 1)
{
Message::SendFail("Syntax error: NbAlongV should be >=1");
return 1;
}
}
else if (aParam == "-nbalong" || aParam == "-nbuv")
{
++anArgIter;
aNbAlongU = anArgIter < theArgNum ? Draw::Atoi(theArgs[anArgIter]) : 0;
aNbAlongV = aNbAlongU;
if (aNbAlongU < 1)
{
Message::SendFail("Syntax error: NbAlong should be >=1");
return 1;
}
}
else
{
Message::SendFail() << "Syntax error: unknown argument '" << aParam << "'";
return 1;
}
}
if (isOn)
{
if (aShapePrs.IsNull())
{
aShapePrs = new MyShapeWithNormals(aShape);
}
aShapePrs->ToUseMesh = isUseMesh;
aShapePrs->ToOrient = isOriented;
aShapePrs->NormalLength = aLength;
aShapePrs->NbAlongU = aNbAlongU;
aShapePrs->NbAlongV = aNbAlongV;
VDisplayAISObject(aShapeName, aShapePrs);
}
else if (!aShapePrs.IsNull())
{
VDisplayAISObject(aShapeName, new AIS_Shape(aShape));
}
return 0;
}
//=================================================================================================
void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
{
const char* aGroup = "AIS Viewer";
const char* aFileName = __FILE__;
auto addCmd =
[&](const char* theName, Draw_Interpretor::CommandFunction theFunc, const char* theHelp) {
theCommands.Add(theName, theHelp, aFileName, theFunc, aGroup);
};
addCmd("vtrihedron", VTrihedron, /* [vtrihedron] */ R"(
vtrihedron name
[-dispMode {wireframe|shading} ]
[-origin x y z ]
[-zaxis u v w -xaxis u v w ]
[-drawAxes {X|Y|Z|XY|YZ|XZ|XYZ}]
[-hideLabels {on|off}]
[-hideArrows {on|off}]
[-label {XAxis|YAxis|ZAxis} value]
[-attribute {XAxisLength|YAxisLength|ZAxisLength
|TubeRadiusPercent|ConeRadiusPercent
|ConeLengthPercent|OriginRadiusPercent
|ShadingNumberOfFacettes} value]
[-color {Origin|XAxis|YAxis|ZAxis|XOYAxis|YOZAxis
|XOZAxis|Whole} {r g b | colorName}]
[-textColor [XAxis|YAxis|ZAxis] {r g b | colorName}]
[-arrowColor [XAxis|YAxis|ZAxis] {r g b | colorName}]
[-priority {Origin|XAxis|YAxis|ZAxis|XArrow
|YArrow|ZArrow|XOYAxis|YOZAxis
|XOZAxis|Whole} value]
Creates/changes *AIS_Trihedron* object.
-dispMode mode of visualization: wf - wireframe,
sh - shading;
default value is wireframe;
-origin allows to set trihedron location;
-zaxis/-xaxis allows to set trihedron X and Z directions;
the directions should be orthogonal;
Y direction is calculated;
-drawAxes allows to set what axes are drawn in the
trihedron, default state is XYZ;
-hideLabels allows to show/hide trihedron labels;
-hideArrows allows to show/hide trihedron arrows;
-label allows to change default X/Y/Z titles of axes;
-attribute sets parameters of trihedron;
-color sets color properties of parts of trihedron;
-textColor sets color properties of trihedron labels;
-arrowColor sets color properties of trihedron arrows;
-priority allows to change default selection priority
of trihedron components.
)" /* [vtrihedron] */);
addCmd("vtri2d", VTrihedron2D, /* [vtri2d] */ R"(
vtri2d Name : Creates a plane with a 2D trihedron from an interactively selected face.
)" /* [vtri2d] */);
addCmd("vplanetri", VPlaneTrihedron, /* [vplanetri] */ R"(
vplanetri name
Create a plane from a trihedron selection.
If no arguments are set, the default plane is created.
)" /* [vplanetri] */);
addCmd("vsize", VSize, /* [vsize] */ R"(
vsize [name(Default=Current)] [size(Default=100)]
Changes the size of a named or selected trihedron.
If the name is not defined: it affects the selected trihedrons otherwise nothing is done.
If the value is not defined: it is set to 100 by default.
)" /* [vsize] */);
addCmd("vaxis", VAxisBuilder, /* [vaxis] */ R"(
vaxis name [Xa] [Ya] [Za] [Xb] [Yb] [Zb]
Creates an axis. If the values are not defined,
an axis is created by interactive selection of two vertices or one edge.
)" /* [vaxis] */);
addCmd("vaxispara", VAxisBuilder, /* [vaxispara] */ R"(
vaxispara name
Creates an axis by interactive selection of an edge and a vertex.
)" /* [vaxispara] */);
addCmd("vaxisortho", VAxisBuilder, /* [vaxisortho] */ R"(
vaxisortho name
Creates an axis by interactive selection of an edge and a vertex.
The axis will be orthogonal to the selected edge.
)" /* [vaxisortho] */);
addCmd("vpoint", VPointBuilder, /* [vpoint] */ R"(
vpoint name [X Y [Z]] [-2d] [-nosel]
Creates a point from coordinates.
If the values are not defined, a point is created from selected vertex or edge (center).
-2d defines on-screen 2D point from top-left window corner;
-nosel creates non-selectable presentation.
)" /* [vpoint] */);
addCmd("vplane", VPlaneBuilder, /* [vplane] */ R"(
vplane PlaneName [AxisName/PlaneName/PointName]
[PointName/PointName/PointName] [Nothing/Nothing/PointName] [TypeOfSensitivity {0|1}]
Creates a plane from named or interactively selected entities. TypeOfSensitivity:
0 - Interior;
1 - Boundary.
)" /* [vplane] */);
addCmd("vchangeplane", VChangePlane, /* [vchangeplane] */ R"(
vchangeplane plane_name
[x=center_x y=center_y z=center_z]
[dx=dir_x dy=dir_y dz=dir_z]
[sx=size_x sy=size_y]
[minsize=value]
[noupdate]
Changes parameters of the plane:
- x y z - center
- dx dy dz - normal
- sx sy - plane sizes
- noupdate - do not update/redisplay the plane in context
Please enter coordinates in format "param=value" in arbitrary order.
)" /* [vchangeplane] */);
addCmd("vplanepara", VPlaneBuilder, /* [vplanepara] */ R"(
vplanepara PlaneName
Creates a plane from interactively selected vertex and face.
)" /* [vplanepara] */);
addCmd("vplaneortho", VPlaneBuilder, /* [vplaneortho] */ R"(
vplaneortho PlaneName
Creates a plane from interactive selected face and coplanar edge.
)" /* [vplaneortho] */);
addCmd("vline", VLineBuilder, /* [vline] */ R"(
vline LineName [Xa/PointName] [Ya/PointName] [Za] [Xb] [Yb] [Zb]
Creates a line from coordinates, named or interactively selected vertices.
)" /* [vline] */);
addCmd("vcircle", VCircleBuilder, /* [vcircle] */ R"(
vcircle CircleName [PointName PointName PointName IsFilled] [UStart UEnd]
[PlaneName PointName Radius IsFilled] [UStart UEnd]
Creates a circle from named or interactively selected entities.
Parameter IsFilled is defined as 0 or 1.
)" /* [vcircle] */);
addCmd("vdrawtext", VDrawText, /* [vdrawtext] */ R"(
vdrawtext name text
[-pos X Y Z]={0 0 0}
[-color {R G B|name}]=yellow
[-halign {left|center|right}]=left
[-valign {top|center|bottom|topfirstline}}]=bottom
[-angle angle]=0
[-zoom {0|1}]=0
[-height height]=16
[-wrapping width]=40
[-wordwrapping {0|1}]=1
[-aspect {regular|bold|italic|boldItalic}]=regular
[-font font]=Times
[-2d] [-perspos {X Y Z}]={0 0 0}
[-disptype {blend|decal|shadow|subtitle|dimension|normal}}=normal
[-subcolor {R G B|name}]=white
[-noupdate]
[-plane NormX NormY NormZ DirX DirY DirZ]
[-flipping] [-ownanchor {0|1}]=1
Display text label at specified position.
Within -perspos, X and Y define the coordinate origin in 2d space relative to the view window.
Example: X=0 Y=0 is center, X=1 Y=1 is upper right corner etc...
Z coordinate defines the gap from border of view window (except center position).
)" /* [vdrawtext] */);
addCmd("vdrawsphere", VDrawSphere, /* [vdrawsphere] */ R"(
vdrawsphere shapeName Fineness [X=0.0 Y=0.0 Z=0.0] [Radius=100.0] [ToShowEdges=0] [ToPrintInfo=1]
)" /* [vdrawsphere] */);
addCmd("vlocation", VSetLocation, /* [vlocation] */ R"(
vlocation name
[-reset] [-copyFrom otherName]
[-translate X Y [Z]] [-rotate x y z dx dy dz angle] [-scale [X Y Z] scale]
[-pretranslate X Y [Z]] [-prerotate x y z dx dy dz angle] [-prescale [X Y Z] scale]
[-mirror x y z dx dy dz] [-premirror x y z dx dy dz]
[-setLocation X Y [Z]] [-setRotation QX QY QZ QW] [-setScale [X Y Z] scale]
Object local transformation management:
-reset resets transformation to identity
-translate applies translation vector
-rotate applies rotation around axis
-scale applies scale factor with optional anchor
-mirror applies mirror transformation
-pretranslate pre-multiplies translation vector
-prerotate pre-multiplies rotation around axis
-prescale pre-multiplies scale transformation
-premirror pre-multiplies mirror transformation
-setLocation overrides translation part
-setRotation overrides rotation part with specified quaternion
-setScale overrides scale factor
)" /* [vlocation] */);
addCmd("vsetlocation", VSetLocation, /* [vsetlocation] */ R"(
Alias for vlocation
)" /* [vsetlocation] */);
addCmd("vchild", VChild, /* [vchild] */ R"(
vchild parent [-add] [-remove] [-ignoreParentTrsf {0|1}] child1 [child2] [...]
Command for testing low-level presentation connections.
vconnect command should be used instead.
)" /* [vchild] */);
addCmd("vparent", VParent, /* [vparent] */ R"(
vparent parent [-ignoreVisu]
Command for testing object properties as parent in the hierarchy.
-ignoreVisu do not propagate the visual state (display/erase/color) to children objects
)" /* [vparent] */);
addCmd("vcomputehlr", VComputeHLR, /* [vcomputehlr] */ R"(
vcomputehlr shapeInput hlrResult [-algoType {algo|polyAlgo}=polyAlgo]
[eyeX eyeY eyeZ dirX dirY dirZ upX upY upZ]
[-showTangentEdges {on|off}=off] [-nbIsolines N=0] [-showHiddenEdges {on|off}=off]
Arguments:
shapeInput - name of the initial shape
hlrResult - result HLR object from initial shape
eye, dir are eye position and look direction
up is the look up direction vector
-algoType HLR algorithm to use
-showTangentEdges include tangent edges
-nbIsolines include isolines
-showHiddenEdges include hidden edges
Use vtop to see projected HLR shape.
)" /* [vcomputehlr] */);
addCmd("vdrawparray", VDrawPArray, /* [vdrawparray] */ R"(
vdrawparray name TypeOfArray={points|segments|polylines|triangles
|trianglefans|trianglestrips|quads|quadstrips|polygons}
[-deinterleaved|-mutable]
[vertex={'v' x y z [normal={'n' nx ny nz}] [color={'c' r g b}] [texel={'t' tx ty}]]
[bound= {'b' nbVertices [bound_color={'c' r g b}]]
[edge= {'e' vertexId]
[-shape shapeName] [-patch]
Commands create an Interactive Object for specified Primitive Array definition
with the main purpose is covering various combinations by tests.
)" /* [vdrawparray] */);
addCmd("vconnect", VConnect, /* [vconnect] */ R"(
vconnect name Xo Yo Zo object1 object2 ... [color=NAME]
Creates and displays AIS_ConnectedInteractive object from input object and location.
)" /* [vconnect] */);
addCmd("vconnectto", VConnectTo, /* [vconnectto] */ R"(
vconnectto instance_name Xo Yo Zo object [-nodisplay|-noupdate|-update]
Makes an instance 'instance_name' of 'object' with position (Xo Yo Zo).
-nodisplay - only creates interactive object, but not displays it.
)" /* [vconnectto] */);
addCmd("vdisconnect", VDisconnect, /* [vdisconnect] */ R"(
vdisconnect assembly_name {object_name|object_number|'all'}
Disconnects all objects from assembly or disconnects object by name or number.
Use vlistconnected to enumerate assembly children.
)" /* [vdisconnect] */);
addCmd("vaddconnected", VAddConnected, /* [vaddconnected] */ R"(
vaddconnected assembly_name object_name
Adds object to assembly.
)" /* [vaddconnected] */);
addCmd("vlistconnected", VListConnected, /* [vlistconnected] */ R"(
vlistconnected assembly_name
Lists objects in assembly.
)" /* [vlistconnected] */);
addCmd("vselmode", VSetSelectionMode, /* [vselmode] */ R"(
vselmode [object] selectionMode {on|off}
[{-add|-set|-globalOrLocal}=-globalOrLocal]
Switches selection mode for the specified object or for all objects in context.
Selection mode is either an integer number specific to Interactive Object,
or sub-shape type in case of AIS_Shape:
Shape, Vertex, Edge, Wire, Face, Shell, Solid, CompSolid, Compound
The integer mode 0 (Shape in case of AIS_Shape) is reserved for selecting object as whole.
Additional options:
-add already activated selection modes will be left activated
-set already activated selection modes will be deactivated
-globalOrLocal (default) if new mode is Global selection mode,
then active local selection modes will be deactivated
and the samthen active local selection modes will be deactivated
)" /* [vselmode] */);
addCmd("vselnext", VSelectionNext, /* [vselnext] */ R"(
vselnext : hilight next detected
)" /* [vselnext] */);
addCmd("vselprev", VSelectionPrevious, /* [vselprev] */ R"(
vselnext : hilight previous detected
)" /* [vselprev] */);
addCmd("vtriangle", VTriangle, /* [vtriangle] */ R"(
vtriangle Name PointName PointName PointName
Creates and displays a filled triangle from named points.
)" /* [vtriangle] */);
addCmd("vsegment", VTriangle, /* [vsegment] */ R"(
vsegment Name PointName PointName
Creates and displays a segment from named points.
)" /* [vsegment] */);
addCmd("vtorus", VTorus, /* [vtorus] */ R"(
vtorus name [R1 R2 [Angle1=0 Angle2=360] [Angle=360]]
[-radius R1] [-pipeRadius R2]
[-pipeAngle Angle=360] [-segmentAngle1 Angle1=0 -segmentAngle2 Angle2=360]
[-nbSlices Number=100] [-nbStacks Number=100] [-noupdate]
Creates and displays a torus or torus segment.
Parameters of the torus:
- R1 distance from the center of the pipe to the center of the torus
- R2 radius of the pipe
- Angle1 first angle to create a torus ring segment
- Angle2 second angle to create a torus ring segment
- Angle angle to create a torus pipe segment
)" /* [vtorus] */);
addCmd("vcylinder", VCylinder, /* [vcylinder] */ R"(
vcylinder name [R1 R2 Height] [-height H] [-radius R] [-bottomRadius R1 -topRadius R2]
[-nbSlices Number=100] [-noupdate]
Creates and displays a cylinder.
Parameters of the cylinder:
- R1 cylinder bottom radius
- R2 cylinder top radius
- Height cylinder height
)" /* [vcylinder] */);
addCmd("vsphere", VSphere, /* [vsphere] */ R"(
vsphere name [-radius] R
[-nbSlices Number=100] [-nbStacks Number=100] [-noupdate]
Creates and displays a sphere.
)" /* [vsphere] */);
addCmd("vobjzlayer", VObjZLayer, /* [vobjzlayer] */ R"(
vobjzlayer : set/get object [layerid] - set or get z layer id for the interactive object
)" /* [vobjzlayer] */);
addCmd("vpolygonoffset", VPolygonOffset, /* [vpolygonoffset] */ R"(
vpolygonoffset [object [mode factor units]]
Sets/gets polygon offset parameters for an object; without arguments prints the default values
)" /* [vpolygonoffset] */);
addCmd("vmarkerstest", VMarkersTest, /* [vmarkerstest] */ R"(
vmarkerstest: name X Y Z [PointsOnSide=10] [MarkerType=0] [Scale=1.0] [FileName=ImageFile]
)" /* [vmarkerstest] */);
addCmd("text2brep", TextToBRep, /* [text2brep] */ R"(
text2brep name text"
[-pos X=0 Y=0 Z=0]"
[-halign {left|center|right}=left]"
[-valign {top|center|bottom|topfirstline}=bottom}]"
[-height height=16]"
[-aspect {regular|bold|italic|boldItalic}=regular]"
[-font font=Courier] [-strict {strict|aliases|any}=any]"
[-composite {on|off}=off]"
[-plane NormX NormY NormZ DirX DirY DirZ]",
)" /* [text2brep] */);
addCmd("vfont", VFont, /* [vfont] */ R"(
vfont [-add pathToFont [fontName] [regular,bold,italic,boldItalic=undefined] [singleStroke]]
[-strict {any|aliases|strict}] [-find fontName [regular,bold,italic,boldItalic=undefined]]
[-verbose {on|off}]
[-findAll fontNameMask] [-findInfo fontName]
[-unicodeFallback {on|off}]
[-clear] [-init] [-list] [-names]
[-aliases [aliasName]] [-addAlias Alias FontName] [-removeAlias Alias FontName]
[-clearAlias Alias] [-clearAliases]
Work with font registry - register font, list available fonts, find font.
-findAll is same as -find, but can print more than one font when mask is passed.
-findInfo is same as -find, but prints complete font information instead of family name.
)" /* [vfont] */);
addCmd("vvertexmode", VVertexMode, /* [vvertexmode] */ R"(
vvertexmode [name | -set {isolated|all|inherited} [name1 name2 ...]]
Sets the vertex draw mode for the specified object(s)
or sets default vertex draw mode and updates the mode for all displayed objects.
Prints the default vertex draw mode without -set parameter.
)" /* [vvertexmode] */);
addCmd("vpointcloud", VPointCloud, /* [vpointcloud] */ R"(
vpointcloud name shape [-randColor {0|1}]=0 [-normals {0|1}]=1 [-uv {0|1}]=0
[-distance Value]=0.0 [-density Value] [-tolerance Value]
Create an interactive object for arbitrary set of points from triangulated shape.
vpointcloud name {-surface|-volume} x y z r npts
[-randColor] [-normals] [-uv]
Create arbitrary set of points (npts) randomly distributed
on spheric surface or within spheric volume (x y z r).
Additional options:
-normals generate or not normal per point
-uv generate UV (texel) coordinates per point
-randColor generate random color per point
-distance distance from shape into the range [0, Value];
-density density of points to generate randomly on surface;
-tolerance cloud generator's tolerance; default value is Precision::Confusion();
)" /* [vpointcloud] */);
addCmd("vpriority", VPriority, /* [vpriority] */ R"(
vpriority [-noupdate|-update] name [value]
Prints or sets the display priority for an object.
)" /* [vpriority] */);
addCmd("vnormals", VNormals, /* [vnormals] */ R"(
vnormals Shape [{on|off}=on] [-length {10}] [-nbAlongU {1}] [-nbAlongV {1}] [-nbAlong {1}]
[-useMesh] [-oriented {0}1}=0]
Displays/Hides normals calculated on shape geometry or retrieved from triangulation
)" /* [vnormals] */);
}
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.