#include <gp_Dir.hxx>
#include <gp_Vec.hxx>
#include <gp_Pnt.hxx>
+#include <NCollection_IncAllocator.hxx>
#include <NCollection_List.hxx>
+#include <NCollection_Shared.hxx>
#include <Precision.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_IsoAspect.hxx>
const TopoDS_Shape& theShape,
const Handle (Prs3d_Drawer)& theDrawer)
{
- Standard_Boolean aDrawAllVerticesFlag = (theDrawer->VertexDrawMode() == Prs3d_VDM_All);
-
- if (!aDrawAllVerticesFlag && theShape.ShapeType() != TopAbs_COMPOUND)
+ TopExp_Explorer aShapeIter (theShape, TopAbs_FACE);
+ if (!aShapeIter.More())
{
+ StdPrs_WFShape::Add (thePrs, theShape, theDrawer);
return;
}
- TopExp_Explorer aShapeIter (theShape, TopAbs_FACE);
- if (!aShapeIter.More())
+ const Standard_Boolean aDrawAllVerticesFlag = (theDrawer->VertexDrawMode() == Prs3d_VDM_All);
+ if (!aDrawAllVerticesFlag && theShape.ShapeType() != TopAbs_COMPOUND)
{
- // compound contains no shaded elements at all
- StdPrs_WFShape::Add (thePrs, theShape, theDrawer);
return;
}
// Determinant of transform matrix less then 0 means that mirror transform applied.
Standard_Boolean isMirrored = aTrsf.VectorialPart().Determinant() < 0;
- Poly_Connect aPolyConnect (aT);
// Extracts vertices & normals from nodes
const TColgp_Array1OfPnt& aNodes = aT->Nodes();
- const TColgp_Array1OfPnt2d& aUVNodes = aT->UVNodes();
- TColgp_Array1OfDir aNormals (aNodes.Lower(), aNodes.Upper());
- StdPrs_ToolTriangulatedShape::Normal (aFace, aPolyConnect, aNormals);
+ const TColgp_Array1OfPnt2d* aUVNodes = theHasTexels && aT->HasUVNodes() && aT->UVNodes().Upper() == aNodes.Upper()
+ ? &aT->UVNodes()
+ : NULL;
+ StdPrs_ToolTriangulatedShape::ComputeNormals (aFace, aT);
+ const TShort_Array1OfShortReal& aNormals = aT->Normals();
+ const Standard_ShortReal* aNormArr = &aNormals.First();
if (theHasTexels)
{
for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
{
aPoint = aNodes (aNodeIter);
+ const Standard_Integer anId = 3 * (aNodeIter - aNodes.Lower());
+ gp_Dir aNorm (aNormArr[anId + 0], aNormArr[anId + 1], aNormArr[anId + 2]);
+ if ((aFace.Orientation() == TopAbs_REVERSED) ^ isMirrored)
+ {
+ aNorm.Reverse();
+ }
if (!aLoc.IsIdentity())
{
aPoint.Transform (aTrsf);
-
- aNormals (aNodeIter) = aNormals (aNodeIter).Transformed (aTrsf);
+ aNorm.Transform (aTrsf);
}
- if (theHasTexels && aUVNodes.Upper() == aNodes.Upper())
+ if (aUVNodes != NULL)
{
- const gp_Pnt2d aTexel = gp_Pnt2d ((-theUVOrigin.X() + (theUVRepeat.X() * (aUVNodes (aNodeIter).X() - aUmin)) / dUmax) / theUVScale.X(),
- (-theUVOrigin.Y() + (theUVRepeat.Y() * (aUVNodes (aNodeIter).Y() - aVmin)) / dVmax) / theUVScale.Y());
- anArray->AddVertex (aPoint, aNormals (aNodeIter), aTexel);
+ const gp_Pnt2d aTexel = (dUmax == 0.0 || dVmax == 0.0)
+ ? aUVNodes->Value (aNodeIter)
+ : gp_Pnt2d ((-theUVOrigin.X() + (theUVRepeat.X() * (aUVNodes->Value (aNodeIter).X() - aUmin)) / dUmax) / theUVScale.X(),
+ (-theUVOrigin.Y() + (theUVRepeat.Y() * (aUVNodes->Value (aNodeIter).Y() - aVmin)) / dVmax) / theUVScale.Y());
+ anArray->AddVertex (aPoint, aNorm, aTexel);
}
else
{
- anArray->AddVertex (aPoint, aNormals (aNodeIter));
+ anArray->AddVertex (aPoint, aNorm);
}
}
Standard_Integer anIndex[3];
for (Standard_Integer aTriIter = 1; aTriIter <= aT->NbTriangles(); ++aTriIter)
{
- if ((aFace.Orientation() == TopAbs_REVERSED) ^ isMirrored)
+ if ((aFace.Orientation() == TopAbs_REVERSED))
{
aTriangles (aTriIter).Get (anIndex[0], anIndex[2], anIndex[1]);
}
aV1.Cross (aV2);
if (aV1.SquareMagnitude() > aPreci)
{
- anArray->AddEdge (anIndex[0] + aDecal);
- anArray->AddEdge (anIndex[1] + aDecal);
- anArray->AddEdge (anIndex[2] + aDecal);
+ anArray->AddEdges (anIndex[0] + aDecal,
+ anIndex[1] + aDecal,
+ anIndex[2] + aDecal);
}
}
}
}
//! Compute boundary presentation for faces of the shape.
- static Handle(Graphic3d_ArrayOfSegments) fillFaceBoundaries (const TopoDS_Shape& theShape)
+ static Handle(Graphic3d_ArrayOfSegments) fillFaceBoundaries (const TopoDS_Shape& theShape,
+ GeomAbs_Shape theUpperContinuity)
{
// collection of all triangulation nodes on edges
// for computing boundaries presentation
Standard_Integer aNbPolylines = 0;
TopLoc_Location aTrsf;
- TColgp_SequenceOfPnt aSeqPntsExtra;
+
+ Handle(NCollection_Shared<TColgp_SequenceOfPnt>) aSeqPntsExtra;
for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
{
const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
- TopoDS_Iterator aSubShapeIter (aFace);
- if (!aSubShapeIter.More())
+ if (aFace.NbChildren() == 0)
{
// handle specifically faces without boundary definition (triangulation-only)
- StdPrs_WFShape::AddEdgesOnTriangulation (aSeqPntsExtra, aFace, Standard_False);
+ if (aSeqPntsExtra.IsNull())
+ {
+ Handle(NCollection_IncAllocator) anIncAlloc = new NCollection_IncAllocator();
+ aSeqPntsExtra = new NCollection_Shared<TColgp_SequenceOfPnt> (anIncAlloc);
+ }
+ StdPrs_WFShape::AddEdgesOnTriangulation (*aSeqPntsExtra, aFace, Standard_False);
}
}
}
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key());
+ if (theUpperContinuity < GeomAbs_CN
+ && anEdgeIter.Value().Extent() >= 2
+ && BRep_Tool::MaxContinuity (anEdge) > theUpperContinuity)
+ {
+ continue;
+ }
+
Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf);
if (!anEdgePoly.IsNull()
&& anEdgePoly->Nodes().Length() >= 2)
++aNbPolylines;
}
}
+ const Standard_Integer aNbExtra = !aSeqPntsExtra.IsNull() ? aSeqPntsExtra->Size() : 0;
if (aNodeNumber == 0)
{
- if (aSeqPntsExtra.Size() < 2)
+ if (aNbExtra < 2)
{
return Handle(Graphic3d_ArrayOfSegments)();
}
- Standard_Integer aNbVertices = aSeqPntsExtra.Size();
- Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNbVertices);
- for (Standard_Integer aPntIter = 1; aPntIter <= aNbVertices; aPntIter += 2)
+ Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNbExtra);
+ for (TColgp_SequenceOfPnt::Iterator aPntIter (*aSeqPntsExtra); aPntIter.More(); aPntIter.Next())
{
- aSegments->AddVertex (aSeqPntsExtra.Value (aPntIter));
- aSegments->AddVertex (aSeqPntsExtra.Value (aPntIter + 1));
+ aSegments->AddVertex (aPntIter.Value());
}
return aSegments;
}
// create indexed segments array to pack polylines from different edges into single array
const Standard_Integer aSegmentEdgeNb = (aNodeNumber - aNbPolylines) * 2;
- Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNodeNumber + aSeqPntsExtra.Size(), aSegmentEdgeNb + aSeqPntsExtra.Size());
+ Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNodeNumber + aNbExtra, aSegmentEdgeNb + aNbExtra);
for (TopTools_IndexedDataMapOfShapeListOfShape::Iterator anEdgeIter (anEdgesMap); anEdgeIter.More(); anEdgeIter.Next())
{
if (anEdgeIter.Value().Extent() == 0)
}
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key());
+ if (theUpperContinuity < GeomAbs_CN
+ && anEdgeIter.Value().Extent() >= 2
+ && BRep_Tool::MaxContinuity (anEdge) > theUpperContinuity)
+ {
+ continue;
+ }
+
Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf);
if (anEdgePoly.IsNull()
|| anEdgePoly->Nodes().Length () < 2)
}
}
+ if (!aSeqPntsExtra.IsNull())
{
Standard_Integer aSegmentEdge = aSegments->VertexNumber();
- const Standard_Integer aNbVertices = aSeqPntsExtra.Size();
- for (Standard_Integer aPntIter = 1; aPntIter <= aNbVertices; aPntIter += 2)
+ for (TColgp_SequenceOfPnt::Iterator aPntIter (*aSeqPntsExtra); aPntIter.More(); aPntIter.Next())
{
- aSegments->AddVertex (aSeqPntsExtra.Value (aPntIter));
- aSegments->AddEdge (++aSegmentEdge);
- aSegments->AddVertex (aSeqPntsExtra.Value (aPntIter + 1));
+ aSegments->AddVertex (aPntIter.Value());
aSegments->AddEdge (++aSegmentEdge);
}
}
return;
}
- // add wireframe presentation for isolated edges and vertices
- wireframeFromShape (thePrs, theShape, theDrawer);
-
// Use automatic re-triangulation with deflection-check logic only if this feature is enable
if (theDrawer->IsAutoTriangulation())
{
StdPrs_ToolTriangulatedShape::Tessellate (theShape, theDrawer);
}
+ // add wireframe presentation for isolated edges and vertices
+ wireframeFromShape (thePrs, theShape, theDrawer);
+
// add special wireframe presentation for faces without triangulation
wireframeNoTriangFacesFromShape (thePrs, theShape, theDrawer);
aBuilder.MakeCompound (anOpened);
ExploreSolids (theShape, aBuilder, aClosed, anOpened, Standard_True);
- TopoDS_Iterator aShapeIter (aClosed);
- if (aShapeIter.More())
+ if (aClosed.NbChildren() > 0)
{
shadeFromShape (aClosed, thePrs, theDrawer,
theHasTexels, theUVOrigin, theUVRepeat, theUVScale, true);
}
- aShapeIter.Initialize (anOpened);
- if (aShapeIter.More())
+ if (anOpened.NbChildren() > 0)
{
shadeFromShape (anOpened, thePrs, theDrawer,
theHasTexels, theUVOrigin, theUVRepeat, theUVScale, false);
if (theDrawer->FaceBoundaryDraw())
{
- Handle(Graphic3d_ArrayOfSegments) aBndSegments = fillFaceBoundaries (theShape);
- if (!aBndSegments.IsNull())
+ if (Handle(Graphic3d_ArrayOfSegments) aBndSegments = fillFaceBoundaries (theShape, theDrawer->FaceBoundaryUpperContinuity()))
{
- Handle(Graphic3d_AspectLine3d) aBoundaryAspect = theDrawer->FaceBoundaryAspect()->Aspect();
- Handle(Graphic3d_Group) aPrsGrp = Prs3d_Root::CurrentGroup (thePrs);
- aPrsGrp->SetGroupPrimitivesAspect (aBoundaryAspect);
+ Handle(Graphic3d_Group) aPrsGrp = thePrs->NewGroup();
+ aPrsGrp->SetGroupPrimitivesAspect (theDrawer->FaceBoundaryAspect()->Aspect());
aPrsGrp->AddPrimitiveArray (aBndSegments);
}
}
// function : FillFaceBoundaries
// purpose :
// =======================================================================
-Handle(Graphic3d_ArrayOfSegments) StdPrs_ShadedShape::FillFaceBoundaries (const TopoDS_Shape& theShape)
+Handle(Graphic3d_ArrayOfSegments) StdPrs_ShadedShape::FillFaceBoundaries (const TopoDS_Shape& theShape,
+ GeomAbs_Shape theUpperContinuity)
{
- return fillFaceBoundaries (theShape);
+ return fillFaceBoundaries (theShape, theUpperContinuity);
}
// =======================================================================