//function : createRoundRectangleTriangles
//purpose :
//=======================================================================
-Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createRoundRectangleTriangles (const gp_XY& theSize,
- Standard_Real theRadius,
- const gp_Trsf& theTrsf)
+void AIS_ViewCube::createRoundRectangleTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ const gp_XY& theSize,
+ Standard_Real theRadius,
+ const gp_Trsf& theTrsf)
{
const Standard_Real aRadius = Min (theRadius, Min (theSize.X(), theSize.Y()) * 0.5);
const gp_XY aHSize (theSize.X() * 0.5 - aRadius, theSize.Y() * 0.5 - aRadius);
const gp_Dir aNorm = gp::DZ().Transformed (theTrsf);
- Handle(Graphic3d_ArrayOfTriangles) aTris;
+ const Standard_Integer aVertFirst = !theTris.IsNull() ? theTris->VertexNumber() : 0;
if (aRadius > 0.0)
{
const Standard_Integer aNbNodes = (THE_NB_ROUND_SPLITS + 1) * 4 + 1;
- aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbNodes * 3, Graphic3d_ArrayFlags_VertexNormal);
+ theNbNodes += aNbNodes;
+ theNbTris += aNbNodes;
+ if (theTris.IsNull())
+ {
+ return;
+ }
- aTris->AddVertex (gp_Pnt (0.0, 0.0, 0.0).Transformed (theTrsf));
+ theTris->AddVertex (gp_Pnt (0.0, 0.0, 0.0).Transformed (theTrsf));
for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
{
const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (M_PI * 0.5, 0.0, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
- aTris->AddVertex (gp_Pnt (aHSize.X() + aRadius * Cos (anAngle), aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
+ theTris->AddVertex (gp_Pnt (aHSize.X() + aRadius * Cos (anAngle), aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
}
for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
{
const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (0.0, -M_PI * 0.5, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
- aTris->AddVertex (gp_Pnt (aHSize.X() + aRadius * Cos (anAngle), -aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
+ theTris->AddVertex (gp_Pnt (aHSize.X() + aRadius * Cos (anAngle), -aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
}
for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
{
const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (-M_PI * 0.5, -M_PI, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
- aTris->AddVertex (gp_Pnt (-aHSize.X() + aRadius * Cos (anAngle), -aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
+ theTris->AddVertex (gp_Pnt (-aHSize.X() + aRadius * Cos (anAngle), -aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
}
for (Standard_Integer aNodeIter = 0; aNodeIter <= THE_NB_ROUND_SPLITS; ++aNodeIter)
{
const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (-M_PI, -M_PI * 1.5, Standard_Real(aNodeIter) / Standard_Real(THE_NB_ROUND_SPLITS));
- aTris->AddVertex (gp_Pnt (-aHSize.X() + aRadius * Cos (anAngle), aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
+ theTris->AddVertex (gp_Pnt (-aHSize.X() + aRadius * Cos (anAngle), aHSize.Y() + aRadius * Sin (anAngle), 0.0).Transformed (theTrsf));
}
// split triangle fan
- for (Standard_Integer aNodeIter = 2; aNodeIter <= aTris->VertexNumber(); ++aNodeIter)
- {
- aTris->AddEdge (1);
- aTris->AddEdge (aNodeIter - 1);
- aTris->AddEdge (aNodeIter);
- }
- aTris->AddEdge (1);
- aTris->AddEdge (aTris->VertexNumber());
- aTris->AddEdge (2);
+ theTris->AddTriangleFanEdges (aVertFirst + 1, theTris->VertexNumber(), true);
}
else
{
- aTris = new Graphic3d_ArrayOfTriangles (4, 6, Graphic3d_ArrayFlags_VertexNormal);
- aTris->AddVertex (gp_Pnt (-aHSize.X(), -aHSize.Y(), 0.0).Transformed (theTrsf));
- aTris->AddVertex (gp_Pnt (-aHSize.X(), aHSize.Y(), 0.0).Transformed (theTrsf));
- aTris->AddVertex (gp_Pnt ( aHSize.X(), aHSize.Y(), 0.0).Transformed (theTrsf));
- aTris->AddVertex (gp_Pnt ( aHSize.X(), -aHSize.Y(), 0.0).Transformed (theTrsf));
- aTris->AddEdges (3, 1, 2);
- aTris->AddEdges (1, 3, 4);
+ theNbNodes += 4;
+ theNbTris += 2;
+ if (theTris.IsNull())
+ {
+ return;
+ }
+
+ theTris->AddVertex (gp_Pnt (-aHSize.X(), -aHSize.Y(), 0.0).Transformed (theTrsf));
+ theTris->AddVertex (gp_Pnt (-aHSize.X(), aHSize.Y(), 0.0).Transformed (theTrsf));
+ theTris->AddVertex (gp_Pnt ( aHSize.X(), aHSize.Y(), 0.0).Transformed (theTrsf));
+ theTris->AddVertex (gp_Pnt ( aHSize.X(), -aHSize.Y(), 0.0).Transformed (theTrsf));
+ theTris->AddQuadTriangleEdges (aVertFirst + 1, aVertFirst + 2, aVertFirst + 3, aVertFirst + 4);
}
- for (Standard_Integer aVertIter = 1; aVertIter <= aTris->VertexNumber(); ++aVertIter)
+ for (Standard_Integer aVertIter = aVertFirst + 1; aVertIter <= theTris->VertexNumber(); ++aVertIter)
{
- aTris->SetVertexNormal (aVertIter, -aNorm);
+ theTris->SetVertexNormal (aVertIter, -aNorm);
}
- return aTris;
}
//=======================================================================
//function : createBoxPartTriangles
//purpose :
//=======================================================================
-Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createBoxPartTriangles (V3d_TypeOfOrientation theDir) const
+void AIS_ViewCube::createBoxPartTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ V3d_TypeOfOrientation theDir) const
{
if (IsBoxSide (theDir))
{
- return createBoxSideTriangles (theDir);
+ createBoxSideTriangles (theTris, theNbNodes, theNbTris, theDir);
}
else if (IsBoxEdge (theDir)
&& myToDisplayEdges)
{
- return createBoxEdgeTriangles (theDir);
+ createBoxEdgeTriangles (theTris, theNbNodes, theNbTris, theDir);
}
else if (IsBoxCorner (theDir)
&& myToDisplayVertices)
{
- return createBoxCornerTriangles (theDir);
+ createBoxCornerTriangles (theTris, theNbNodes, theNbTris, theDir);
}
- return Handle(Graphic3d_ArrayOfTriangles)();
}
//=======================================================================
//function : createBoxSideTriangles
//purpose :
//=======================================================================
-Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createBoxSideTriangles (V3d_TypeOfOrientation theDirection) const
+void AIS_ViewCube::createBoxSideTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ V3d_TypeOfOrientation theDirection) const
{
const gp_Dir aDir = V3d::GetProjAxis (theDirection);
const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 + myBoxFacetExtension);
gp_Trsf aTrsf;
aTrsf.SetTransformation (aSystem, gp_Ax3());
- return createRoundRectangleTriangles (gp_XY (mySize, mySize), myRoundRadius * mySize, aTrsf);
+ createRoundRectangleTriangles (theTris, theNbNodes, theNbTris,
+ gp_XY (mySize, mySize), myRoundRadius * mySize, aTrsf);
}
//=======================================================================
//function : createBoxEdgeTriangles
//purpose :
//=======================================================================
-Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createBoxEdgeTriangles (V3d_TypeOfOrientation theDirection) const
+void AIS_ViewCube::createBoxEdgeTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ V3d_TypeOfOrientation theDirection) const
{
const Standard_Real aThickness = Max (myBoxFacetExtension * gp_XY (1.0, 1.0).Modulus() - myBoxEdgeGap, myBoxEdgeMinSize);
gp_Trsf aTrsf;
aTrsf.SetTransformation (aSystem, gp_Ax3());
- return createRoundRectangleTriangles (gp_XY (aThickness, mySize), myRoundRadius * mySize, aTrsf);
+ createRoundRectangleTriangles (theTris, theNbNodes, theNbTris,
+ gp_XY (aThickness, mySize), myRoundRadius * mySize, aTrsf);
}
//=======================================================================
//function : createBoxCornerTriangles
//purpose :
//=======================================================================
-Handle(Graphic3d_ArrayOfTriangles) AIS_ViewCube::createBoxCornerTriangles (V3d_TypeOfOrientation theDir) const
+void AIS_ViewCube::createBoxCornerTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ V3d_TypeOfOrientation theDir) const
{
const Standard_Real aHSize = mySize * 0.5;
const gp_Dir aDir = V3d::GetProjAxis (theDir);
const gp_XYZ aHSizeDir = aDir.XYZ() * (aHSize * gp_Vec (1.0, 1.0, 1.0).Magnitude());
+ const Standard_Integer aVertFirst = !theTris.IsNull() ? theTris->VertexNumber() : 0;
if (myRoundRadius > 0.0)
{
+ theNbNodes += THE_NB_DISK_SLICES + 1;
+ theNbTris += THE_NB_DISK_SLICES + 1;
+ if (theTris.IsNull())
+ {
+ return;
+ }
+
const Standard_Real anEdgeHWidth = myBoxFacetExtension * gp_XY (1.0, 1.0).Modulus() * 0.5;
const Standard_Real aHeight = anEdgeHWidth * Sqrt (2.0 / 3.0); // tetrahedron height
const gp_Pnt aPos = aDir.XYZ() * (aHSize * gp_Vec (1.0, 1.0, 1.0).Magnitude() + aHeight);
gp_Trsf aTrsf;
aTrsf.SetTransformation (aSystem, gp_Ax3());
const Standard_Real aRadius = Max (myBoxFacetExtension * 0.5 / Cos (M_PI_4), myCornerMinSize);
- return Prs3d_ToolDisk::Create (0.0, aRadius, THE_NB_DISK_SLICES, 1, aTrsf);
- }
-
- Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (3, 3, Graphic3d_ArrayFlags_VertexNormal);
-
- aTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (aDir.X(), 0.0, 0.0).XYZ());
- aTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (0.0, aDir.Y(), 0.0).XYZ());
- aTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (0.0, 0.0, aDir.Z()).XYZ());
- const gp_XYZ aNode1 = aTris->Vertice (1).XYZ();
- const gp_XYZ aNode2 = aTris->Vertice (2).XYZ();
- const gp_XYZ aNode3 = aTris->Vertice (3).XYZ();
- const gp_XYZ aNormTri = ((aNode2 - aNode1).Crossed (aNode3 - aNode1));
- if (aNormTri.Dot (aDir.XYZ()) < 0.0)
- {
- aTris->AddEdges (1, 3, 2);
+ theTris->AddVertex (gp_Pnt (0.0, 0.0, 0.0).Transformed (aTrsf));
+ for (Standard_Integer aNodeIter = 0; aNodeIter < THE_NB_DISK_SLICES; ++aNodeIter)
+ {
+ const Standard_Real anAngle = NCollection_Lerp<Standard_Real>::Interpolate (2.0 * M_PI, 0.0, Standard_Real(aNodeIter) / Standard_Real(THE_NB_DISK_SLICES));
+ theTris->AddVertex (gp_Pnt (aRadius * Cos (anAngle), aRadius * Sin (anAngle), 0.0).Transformed (aTrsf));
+ }
+ theTris->AddTriangleFanEdges (aVertFirst + 1, theTris->VertexNumber(), true);
}
else
{
- aTris->AddEdges (1, 2, 3);
+ theNbNodes += 3;
+ theNbTris += 1;
+ if (theTris.IsNull())
+ {
+ return;
+ }
+
+ theTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (aDir.X(), 0.0, 0.0).XYZ());
+ theTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (0.0, aDir.Y(), 0.0).XYZ());
+ theTris->AddVertex (aHSizeDir + myBoxFacetExtension * gp_Dir (0.0, 0.0, aDir.Z()).XYZ());
+
+ const gp_XYZ aNode1 = theTris->Vertice (aVertFirst + 1).XYZ();
+ const gp_XYZ aNode2 = theTris->Vertice (aVertFirst + 2).XYZ();
+ const gp_XYZ aNode3 = theTris->Vertice (aVertFirst + 3).XYZ();
+ const gp_XYZ aNormTri = ((aNode2 - aNode1).Crossed (aNode3 - aNode1));
+ if (aNormTri.Dot (aDir.XYZ()) < 0.0)
+ {
+ theTris->AddTriangleEdges (aVertFirst + 1, aVertFirst + 3, aVertFirst + 2);
+ }
+ else
+ {
+ theTris->AddTriangleEdges (aVertFirst + 1, aVertFirst + 2, aVertFirst + 3);
+ }
}
- for (Standard_Integer aVertIter = 1; aVertIter <= aTris->VertexNumber(); ++aVertIter)
+ for (Standard_Integer aVertIter = aVertFirst + 1; aVertIter <= theTris->VertexNumber(); ++aVertIter)
{
- aTris->SetVertexNormal (aVertIter, aDir);
+ theTris->SetVertexNormal (aVertIter, aDir);
}
- return aTris;
}
//=======================================================================
}
}
- // Display box
+ // Display box sides
{
- Handle(Graphic3d_Group) aGroupSides = thePrs->NewGroup(), aGroupEdges = thePrs->NewGroup(), aGroupCorners = thePrs->NewGroup();
- aGroupSides->SetClosed (true); // should be replaced by forced back-face culling aspect
- aGroupSides->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
+ Standard_Integer aNbNodes = 0, aNbTris = 0;
+ for (Standard_Integer aPartIter = V3d_Xpos; aPartIter <= Standard_Integer(V3d_Zneg); ++aPartIter)
+ {
+ createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, (V3d_TypeOfOrientation )aPartIter);
+ }
+ if (aNbNodes > 0)
+ {
+ Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexNormal);
+ Handle(Graphic3d_ArrayOfSegments) aSegs;
+ if (myDrawer->FaceBoundaryDraw())
+ {
+ aSegs = new Graphic3d_ArrayOfSegments (aNbNodes, aNbNodes * 2, Graphic3d_ArrayFlags_None);
+ }
+ aNbNodes = aNbTris = 0;
+ for (Standard_Integer aPartIter = V3d_Xpos; aPartIter <= Standard_Integer(V3d_Zneg); ++aPartIter)
+ {
+ Standard_Integer aTriNodesFrom = aTris->VertexNumber();
+ const Standard_Integer aTriFrom = aNbTris;
+ createBoxPartTriangles (aTris, aNbNodes, aNbTris, (V3d_TypeOfOrientation )aPartIter);
+ if (aSegs.IsNull())
+ {
+ continue;
+ }
+
+ const Standard_Integer aFirstNode = aSegs->VertexNumber();
+ for (Standard_Integer aVertIter = (aNbTris - aTriFrom) > 2 ? aTriNodesFrom + 2 : aTriNodesFrom + 1; // skip triangle fan center
+ aVertIter <= aTris->VertexNumber(); ++aVertIter)
+ {
+ aSegs->AddVertex (aTris->Vertice (aVertIter));
+ }
+ aSegs->AddPolylineEdges (aFirstNode + 1, aSegs->VertexNumber(), true);
+ }
- aGroupEdges->SetClosed (true);
- aGroupEdges->SetGroupPrimitivesAspect (myBoxEdgeAspect->Aspect());
+ {
+ Handle(Graphic3d_Group) aGroupSides = thePrs->NewGroup();
+ aGroupSides->SetClosed (true); // should be replaced by forced back-face culling aspect
+ aGroupSides->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
+ aGroupSides->AddPrimitiveArray (aTris);
+ }
- aGroupCorners->SetClosed (true);
- aGroupCorners->SetGroupPrimitivesAspect (myBoxCornerAspect->Aspect());
+ if (!aSegs.IsNull())
+ {
+ Handle(Graphic3d_Group) aGroupSegs = thePrs->NewGroup();
+ aGroupSegs->SetGroupPrimitivesAspect (myDrawer->FaceBoundaryAspect()->Aspect());
+ aGroupSegs->AddPrimitiveArray (aSegs);
+ }
+ }
+ // Display box sides labels
Handle(Graphic3d_Group) aTextGroup = thePrs->NewGroup();
- //aTextGroup->SetClosed (true);
aTextGroup->SetGroupPrimitivesAspect (myDrawer->TextAspect()->Aspect());
- for (Standard_Integer aPartIter = 0; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter)
+ for (Standard_Integer aPartIter = V3d_Xpos; aPartIter <= Standard_Integer(V3d_Zneg); ++aPartIter)
{
const V3d_TypeOfOrientation anOrient = (V3d_TypeOfOrientation )aPartIter;
- if (Handle(Graphic3d_ArrayOfTriangles) aTris = createBoxPartTriangles (anOrient))
+
+ TCollection_AsciiString aLabel;
+ if (!myBoxSideLabels.Find (anOrient, aLabel)
+ || aLabel.IsEmpty())
{
- if (IsBoxSide (anOrient))
+ continue;
+ }
+
+ const gp_Dir aDir = V3d::GetProjAxis (anOrient);
+ gp_Dir anUp = myIsYup ? gp::DY() : gp::DZ();
+ if (myIsYup)
+ {
+ if (anOrient == V3d_Ypos
+ || anOrient == V3d_Yneg)
{
- aGroupSides->AddPrimitiveArray (aTris);
-
- TCollection_AsciiString aLabel;
- if (!myBoxSideLabels.Find (anOrient, aLabel)
- || aLabel.IsEmpty())
- {
- continue;
- }
-
- const gp_Dir aDir = V3d::GetProjAxis (anOrient);
- gp_Dir anUp = myIsYup ? gp::DY() : gp::DZ();
- if (myIsYup)
- {
- if (anOrient == V3d_Ypos
- || anOrient == V3d_Yneg)
- {
- anUp = -gp::DZ();
- }
- }
- else
- {
- if (anOrient == V3d_Zpos)
- {
- anUp = gp::DY();
- }
- else if (anOrient == V3d_Zneg)
- {
- anUp = -gp::DY();
- }
- }
-
- const Standard_Real anOffset = 2.0; // extra offset to avoid overlapping with triangulation
- const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 + myBoxFacetExtension + anOffset);
- const gp_Ax2 aPosition (aPos, aDir, anUp.Crossed (aDir));
- Prs3d_Text::Draw (aTextGroup, myDrawer->TextAspect(), aLabel, aPosition);
+ anUp = -gp::DZ();
}
- else if (IsBoxEdge (anOrient))
+ }
+ else
+ {
+ if (anOrient == V3d_Zpos)
{
- aGroupEdges->AddPrimitiveArray (aTris);
+ anUp = gp::DY();
}
- else if (IsBoxCorner (anOrient))
+ else if (anOrient == V3d_Zneg)
{
- aGroupCorners->AddPrimitiveArray (aTris);
+ anUp = -gp::DY();
}
}
+
+ const Standard_Real anOffset = 2.0; // extra offset to avoid overlapping with triangulation
+ const gp_Pnt aPos = aDir.XYZ() * (mySize * 0.5 + myBoxFacetExtension + anOffset);
+ const gp_Ax2 aPosition (aPos, aDir, anUp.Crossed (aDir));
+ Prs3d_Text::Draw (aTextGroup, myDrawer->TextAspect(), aLabel, aPosition);
+ }
+ }
+
+ // Display box edges
+ {
+ Standard_Integer aNbNodes = 0, aNbTris = 0;
+ for (Standard_Integer aPartIter = V3d_XposYpos; aPartIter <= Standard_Integer(V3d_YposZneg); ++aPartIter)
+ {
+ createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, (V3d_TypeOfOrientation )aPartIter);
+ }
+ if (aNbNodes > 0)
+ {
+ Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexNormal);
+ aNbNodes = aNbTris = 0;
+ for (Standard_Integer aPartIter = V3d_XposYpos; aPartIter <= Standard_Integer(V3d_YposZneg); ++aPartIter)
+ {
+ const V3d_TypeOfOrientation anOrient = (V3d_TypeOfOrientation )aPartIter;
+ createBoxPartTriangles (aTris, aNbNodes, aNbTris, anOrient);
+ }
+
+ Handle(Graphic3d_Group) aGroupEdges = thePrs->NewGroup();
+ aGroupEdges->SetClosed (true);
+ aGroupEdges->SetGroupPrimitivesAspect (myBoxEdgeAspect->Aspect());
+ aGroupEdges->AddPrimitiveArray (aTris);
+ }
+ }
+
+ // Display box corners
+ {
+ Standard_Integer aNbNodes = 0, aNbTris = 0;
+ for (Standard_Integer aPartIter = V3d_XposYposZpos; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter)
+ {
+ createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, (V3d_TypeOfOrientation )aPartIter);
+ }
+ if (aNbNodes > 0)
+ {
+ Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_VertexNormal);
+ aNbNodes = aNbTris = 0;
+ for (Standard_Integer aPartIter = V3d_XposYposZpos; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter)
+ {
+ const V3d_TypeOfOrientation anOrient = (V3d_TypeOfOrientation )aPartIter;
+ createBoxPartTriangles (aTris, aNbNodes, aNbTris, anOrient);
+ }
+
+ Handle(Graphic3d_Group) aGroupCorners = thePrs->NewGroup();
+ aGroupCorners->SetClosed (true);
+ aGroupCorners->SetGroupPrimitivesAspect (myBoxCornerAspect->Aspect());
+ aGroupCorners->AddPrimitiveArray (aTris);
}
}
}
for (Standard_Integer aPartIter = 0; aPartIter <= Standard_Integer(V3d_XnegYnegZneg); ++aPartIter)
{
const V3d_TypeOfOrientation anOri = (V3d_TypeOfOrientation )aPartIter;
- if (Handle(Graphic3d_ArrayOfTriangles) aTris = createBoxPartTriangles (anOri))
+ Standard_Integer aNbNodes = 0, aNbTris = 0;
+ createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, anOri);
+ if (aNbNodes <= 0)
{
- Standard_Integer aSensitivity = 2;
- if (IsBoxCorner (anOri))
- {
- aSensitivity = 8;
- }
- else if (IsBoxEdge (anOri))
- {
- aSensitivity = 4;
- }
- Handle(AIS_ViewCubeOwner) anOwner = new AIS_ViewCubeOwner (this, anOri);
- Handle(AIS_ViewCubeSensitive) aTriSens = new AIS_ViewCubeSensitive (anOwner, aTris);
- aTriSens->SetSensitivityFactor (aSensitivity);
- theSelection->Add (aTriSens);
+ continue;
}
+
+ Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_None);
+ aNbNodes = aNbTris = 0;
+ createBoxPartTriangles (aTris, aNbNodes, aNbTris, anOri);
+
+ Standard_Integer aSensitivity = 2;
+ if (IsBoxCorner (anOri))
+ {
+ aSensitivity = 8;
+ }
+ else if (IsBoxEdge (anOri))
+ {
+ aSensitivity = 4;
+ }
+ Handle(AIS_ViewCubeOwner) anOwner = new AIS_ViewCubeOwner (this, anOri);
+ Handle(AIS_ViewCubeSensitive) aTriSens = new AIS_ViewCubeSensitive (anOwner, aTris);
+ aTriSens->SetSensitivityFactor (aSensitivity);
+ theSelection->Add (aTriSens);
}
}
return !myViewAnimation->IsStopped();
}
+//=======================================================================
+//function : viewFitAll
+//purpose :
+//=======================================================================
+void AIS_ViewCube::viewFitAll (const Handle(V3d_View)& theView,
+ const Handle(Graphic3d_Camera)& theCamera)
+{
+ Bnd_Box aBndBox = myToFitSelected ? GetContext()->BoundingBoxOfSelection() : theView->View()->MinMaxValues();
+ if (aBndBox.IsVoid()
+ && myToFitSelected)
+ {
+ aBndBox = theView->View()->MinMaxValues();
+ }
+ if (!aBndBox.IsVoid())
+ {
+ theView->FitMinMax (theCamera, aBndBox, 0.01, 10.0 * Precision::Confusion());
+ }
+}
+
//=======================================================================
//function : StartAnimation
//purpose :
myEndState ->Copy (aView->Camera());
{
- Handle(Graphic3d_Camera) aBackupCamera = new Graphic3d_Camera (aView->Camera());
-
- const bool wasImmediateUpdate = aView->SetImmediateUpdate (false);
- aView->SetCamera (myEndState);
- aView->SetProj (theOwner->MainOrientation(), myIsYup);
+ {
+ Handle(Graphic3d_Camera) aBackupCamera = aView->Camera();
+ const bool wasImmediateUpdate = aView->SetImmediateUpdate (false);
+ aView->SetCamera (myEndState);
+ aView->SetProj (theOwner->MainOrientation(), myIsYup);
+ aView->SetCamera (aBackupCamera);
+ aView->SetImmediateUpdate (wasImmediateUpdate);
+ }
- const gp_Dir aNewDir = aView->Camera()->Direction();
+ const gp_Dir aNewDir = myEndState->Direction();
if (!myToResetCameraUp
- && !aNewDir.IsEqual (aBackupCamera->Direction(), Precision::Angular()))
+ && !aNewDir.IsEqual (myStartState->Direction(), Precision::Angular()))
{
// find the Up direction closest to current instead of default one
const gp_Ax1 aNewDirAx1 (gp::Origin(), aNewDir);
- const gp_Dir anOldUp = aBackupCamera->Up();
+ const gp_Dir anOldUp = myStartState->Up();
const gp_Dir anUpList[4] =
{
- aView->Camera()->Up(),
- aView->Camera()->Up().Rotated (aNewDirAx1, M_PI_2),
- aView->Camera()->Up().Rotated (aNewDirAx1, M_PI),
- aView->Camera()->Up().Rotated (aNewDirAx1, M_PI * 1.5),
+ myEndState->Up(),
+ myEndState->Up().Rotated (aNewDirAx1, M_PI_2),
+ myEndState->Up().Rotated (aNewDirAx1, M_PI),
+ myEndState->Up().Rotated (aNewDirAx1, M_PI * 1.5),
};
Standard_Real aBestAngle = Precision::Infinite();
anUpBest = anUpList[anUpIter];
}
}
- aView->Camera()->SetUp (anUpBest);
+ myEndState->SetUp (anUpBest);
}
- const Bnd_Box aBndSelected = myToFitSelected ? GetContext()->BoundingBoxOfSelection() : Bnd_Box();
- if (!aBndSelected.IsVoid())
- {
- aView->FitAll (aBndSelected, 0.01, false);
- }
- else
- {
- aView->FitAll (0.01, false);
- }
- aView->SetCamera (aBackupCamera);
- aView->SetImmediateUpdate (wasImmediateUpdate);
+ viewFitAll (aView, myEndState);
}
myViewAnimation->SetView (aView);
{
Handle(Graphic3d_Group) aGroup = aHiPrs->NewGroup();
aGroup->SetGroupPrimitivesAspect (theStyle->ShadingAspect()->Aspect());
- if (Handle(Graphic3d_ArrayOfTriangles) aTris = createBoxPartTriangles (aCubeOwner->MainOrientation()))
+ Standard_Integer aNbNodes = 0, aNbTris = 0;
+ createBoxPartTriangles (Handle(Graphic3d_ArrayOfTriangles)(), aNbNodes, aNbTris, aCubeOwner->MainOrientation());
+ if (aNbNodes > 0)
{
+ Handle(Graphic3d_ArrayOfTriangles) aTris = new Graphic3d_ArrayOfTriangles (aNbNodes, aNbTris * 3, Graphic3d_ArrayFlags_None);
+ aNbNodes = aNbTris = 0;
+ createBoxPartTriangles (aTris, aNbNodes, aNbTris, aCubeOwner->MainOrientation());
aGroup->AddPrimitiveArray (aTris);
}
}
class AIS_AnimationCamera;
class AIS_ViewCubeOwner;
class Graphic3d_ArrayOfTriangles;
+class V3d_View;
//! Interactive object for displaying the view manipulation cube.
//!
//! @return FALSE if animation has been finished
Standard_EXPORT Standard_Boolean updateAnimation();
+ //! Fit selected/all into view.
+ //! @param theView [in] view definition to retrieve scene bounding box
+ //! @param theCamera [in,out] camera definition
+ Standard_EXPORT virtual void viewFitAll (const Handle(V3d_View)& theView,
+ const Handle(Graphic3d_Camera)& theCamera);
+
protected: //! @name protected virtual API
//! Method that is called after one step of transformation.
protected: //! @name Auxiliary classes to fill presentation with proper primitives
//! Create triangulation for a box part - for presentation and selection purposes.
- Standard_EXPORT virtual Handle(Graphic3d_ArrayOfTriangles) createBoxPartTriangles (V3d_TypeOfOrientation theDir) const;
+ //! @param theTris [in,out] triangulation to fill, or NULL to return size
+ //! @param theNbNodes [in,out] should be incremented by a number of nodes defining this triangulation
+ //! @param theNbTris [in,out] should be incremented by a number of triangles defining this triangulation
+ //! @param theDir [in] part to define
+ Standard_EXPORT virtual void createBoxPartTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ V3d_TypeOfOrientation theDir) const;
//! Create triangulation for a box side.
- Standard_EXPORT virtual Handle(Graphic3d_ArrayOfTriangles) createBoxSideTriangles (V3d_TypeOfOrientation theDir) const;
+ //! @param theTris [in,out] triangulation to fill, or NULL to return size
+ //! @param theNbNodes [in,out] should be incremented by a number of nodes defining this triangulation
+ //! @param theNbTris [in,out] should be incremented by a number of triangles defining this triangulation
+ //! @param theDir [in] part to define
+ Standard_EXPORT virtual void createBoxSideTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ V3d_TypeOfOrientation theDir) const;
//! Create triangulation for a box edge.
- Standard_EXPORT virtual Handle(Graphic3d_ArrayOfTriangles) createBoxEdgeTriangles (V3d_TypeOfOrientation theDir) const;
+ //! @param theTris [in,out] triangulation to fill, or NULL to return size
+ //! @param theNbNodes [in,out] should be incremented by a number of nodes defining this triangulation
+ //! @param theNbTris [in,out] should be incremented by a number of triangles defining this triangulation
+ //! @param theDir [in] part to define
+ Standard_EXPORT virtual void createBoxEdgeTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ V3d_TypeOfOrientation theDir) const;
//! Create triangulation for a box corner (vertex).
- Standard_EXPORT virtual Handle(Graphic3d_ArrayOfTriangles) createBoxCornerTriangles (V3d_TypeOfOrientation theDir) const;
+ //! @param theTris [in,out] triangulation to fill, or NULL to return size
+ //! @param theNbNodes [in,out] should be incremented by a number of nodes defining this triangulation
+ //! @param theNbTris [in,out] should be incremented by a number of triangles defining this triangulation
+ //! @param theDir [in] part to define
+ Standard_EXPORT virtual void createBoxCornerTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ V3d_TypeOfOrientation theDir) const;
protected:
//! Create triangulation for a rectangle with round corners.
- //! @param theSize rectangle dimensions
- //! @param theRadius radius at corners
- //! @param theTrsf transformation
- Standard_EXPORT static Handle(Graphic3d_ArrayOfTriangles) createRoundRectangleTriangles (const gp_XY& theSize,
- Standard_Real theRadius,
- const gp_Trsf& theTrsf);
+ //! @param theTris [in,out] triangulation to fill, or NULL to return size
+ //! @param theNbNodes [in,out] should be incremented by a number of nodes defining this triangulation
+ //! @param theNbTris [in,out] should be incremented by a number of triangles defining this triangulation
+ //! @param theSize [in] rectangle dimensions
+ //! @param theRadius [in] radius at corners
+ //! @param theTrsf [in] transformation
+ Standard_EXPORT static void createRoundRectangleTriangles (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
+ Standard_Integer& theNbNodes,
+ Standard_Integer& theNbTris,
+ const gp_XY& theSize,
+ Standard_Real theRadius,
+ const gp_Trsf& theTrsf);
protected:
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <Standard_OutOfRange.hxx>
+#include <Standard_TypeMismatch.hxx>
#include <Quantity_Color.hxx>
class Graphic3d_ArrayOfPrimitives;
return AddEdge (theVertexIndex2);
}
+ //! Convenience method, adds two vertex indices (a segment) in the range [1,VertexNumber()] in the array of segments (Graphic3d_TOPA_SEGMENTS).
+ //! Raises exception if array is not of type Graphic3d_TOPA_SEGMENTS.
+ //! @return the actual edges number
+ Standard_Integer AddSegmentEdges (Standard_Integer theVertexIndex1,
+ Standard_Integer theVertexIndex2)
+ {
+ Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_SEGMENTS, "Not array of segments");
+ return AddEdges (theVertexIndex1, theVertexIndex2);
+ }
+
//! Convenience method, adds three vertex indices (a triangle) in the range [1,VertexNumber()] in the array.
//! @return the actual edges number
Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
return AddEdge (theVertexIndex3);
}
+ //! Convenience method, adds three vertex indices of triangle in the range [1,VertexNumber()] in the array of triangles.
+ //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
+ //! @return the actual edges number
+ Standard_Integer AddTriangleEdges (Standard_Integer theVertexIndex1,
+ Standard_Integer theVertexIndex2,
+ Standard_Integer theVertexIndex3)
+ {
+ Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_TRIANGLES, "Not array of triangles");
+ return AddEdges (theVertexIndex1, theVertexIndex2, theVertexIndex3);
+ }
+
+ //! Convenience method, adds three vertex indices of triangle in the range [1,VertexNumber()] in the array of triangles.
+ //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
+ //! @return the actual edges number
+ Standard_Integer AddTriangleEdges (const Graphic3d_Vec3i& theIndexes)
+ {
+ Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_TRIANGLES, "Not array of triangles");
+ return AddEdges (theIndexes[0], theIndexes[1], theIndexes[2]);
+ }
+
+ //! Convenience method, adds three vertex indices (4th component is ignored) of triangle in the range [1,VertexNumber()] in the array of triangles.
+ //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
+ //! @return the actual edges number
+ Standard_Integer AddTriangleEdges (const Graphic3d_Vec4i& theIndexes)
+ {
+ Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_TRIANGLES, "Not array of triangles");
+ return AddEdges (theIndexes[0], theIndexes[1], theIndexes[2]);
+ }
+
//! Convenience method, adds four vertex indices (a quad) in the range [1,VertexNumber()] in the array.
//! @return the actual edges number
Standard_Integer AddEdges (Standard_Integer theVertexIndex1,
return AddEdge (theVertexIndex4);
}
+ //! Convenience method, adds four vertex indices (a quad) in the range [1,VertexNumber()] in the array of quads.
+ //! Raises exception if array is not of type Graphic3d_TOPA_QUADRANGLES.
+ //! @return the actual edges number
+ Standard_Integer AddQuadEdges (Standard_Integer theVertexIndex1,
+ Standard_Integer theVertexIndex2,
+ Standard_Integer theVertexIndex3,
+ Standard_Integer theVertexIndex4)
+ {
+ Standard_TypeMismatch_Raise_if (myType != Graphic3d_TOPA_QUADRANGLES, "Not array of quads");
+ return AddEdges (theVertexIndex1, theVertexIndex2, theVertexIndex3, theVertexIndex4);
+ }
+
+ //! Convenience method, adds quad indices in the range [1,VertexNumber()] into array or triangles as two triangles.
+ //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
+ //! @return the actual edges number
+ Standard_Integer AddQuadTriangleEdges (Standard_Integer theVertexIndex1,
+ Standard_Integer theVertexIndex2,
+ Standard_Integer theVertexIndex3,
+ Standard_Integer theVertexIndex4)
+ {
+ AddTriangleEdges (theVertexIndex3, theVertexIndex1, theVertexIndex2);
+ return AddTriangleEdges (theVertexIndex1, theVertexIndex3, theVertexIndex4);
+ }
+
+ //! Convenience method, adds quad indices in the range [1,VertexNumber()] into array or triangles as two triangles.
+ //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
+ //! @return the actual edges number
+ Standard_Integer AddQuadTriangleEdges (const Graphic3d_Vec4i& theIndexes)
+ {
+ return AddQuadTriangleEdges (theIndexes[0], theIndexes[1], theIndexes[2], theIndexes[3]);
+ }
+
+ //! Add triangle strip into indexed triangulation array.
+ //! N-2 triangles are added from N input nodes.
+ //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
+ //! @param theVertexLower [in] index of first node defining triangle strip
+ //! @param theVertexUpper [in] index of last node defining triangle strip
+ Standard_EXPORT void AddTriangleStripEdges (Standard_Integer theVertexLower,
+ Standard_Integer theVertexUpper);
+
+ //! Add triangle fan into indexed triangulation array.
+ //! N-2 triangles are added from N input nodes (or N-1 with closed flag).
+ //! Raises exception if array is not of type Graphic3d_TOPA_TRIANGLES.
+ //! @param theVertexLower [in] index of first node defining triangle fun (center)
+ //! @param theVertexUpper [in] index of last node defining triangle fun
+ //! @param theToClose [in] close triangle fan (connect first and last points)
+ Standard_EXPORT void AddTriangleFanEdges (Standard_Integer theVertexLower,
+ Standard_Integer theVertexUpper,
+ Standard_Boolean theToClose);
+
+ //! Add line strip (polyline) into indexed segments array.
+ //! N-1 segments are added from N input nodes (or N with closed flag).
+ //! Raises exception if array is not of type Graphic3d_TOPA_SEGMENTS.
+ //! @param theVertexLower [in] index of first node defining line strip fun (center)
+ //! @param theVertexUpper [in] index of last node defining triangle fun
+ //! @param theToClose [in] close triangle fan (connect first and last points)
+ Standard_EXPORT void AddPolylineEdges (Standard_Integer theVertexLower,
+ Standard_Integer theVertexUpper,
+ Standard_Boolean theToClose);
+
public: //! @name optional array of Bounds/Subgroups within primitive array (e.g. restarting primitives / assigning colors)
//! Returns optional bounds buffer.