1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-08 14:17:06 +03:00

0031458: Visualization - refine classes across Prs3d and StdPrs packages

Prs3d::GetDeflection() has been moved to StdPrs_ToolTriangulatedShape::GetDeflection().
Prs3d_ShapeTool has been moved to StdPrs_ShapeTool.
Code collecting free edges on Poly_Triangulation
has been moved out from StdPrs_WFShape to Prs3d::AddFreeEdges().
StdPrs_BndBox has been moved to Prs3d_BndBox.
Geom_Transformation has been replaced by TopLoc_Datum3D within visualization classes.

Select3D_SensitiveCircle constructor now takes gp_Circ instead of Geom_Circle.
StdSelect_ViewerSelector3d has been moved to SelectMgr_ViewerSelector3d.
Methods ::GetPoint3d() and ::ArrayBounds() has been moved
from subclass Select3D_SensitiveCircle to the base class Select3D_SensitiveCurve.
StdSelect_ViewerSelector3d::computeSensitivePrs() has been moved to SelectMgr::ComputeSensitivePrs().

Removed unused declarations StdSelect_Prs, StdSelect_DisplayMode,
StdSelect_SensitivityMode, StdSelect_TypeOfResult, SelectMgr_SOPtr, TColQuantity.

Package Graphic3d has been moved from TKV3d to TKService.
This commit is contained in:
kgv
2020-03-14 13:32:48 +03:00
committed by bugmaster
parent 787ff2408c
commit 7f24b768c3
127 changed files with 2215 additions and 2992 deletions

View File

@@ -1,4 +1,7 @@
StdPrs_BndBox.cxx
StdPrs_BRepFont.cxx
StdPrs_BRepFont.hxx
StdPrs_BRepTextBuilder.cxx
StdPrs_BRepTextBuilder.hxx
StdPrs_BndBox.hxx
StdPrs_Curve.cxx
StdPrs_Curve.hxx
@@ -23,6 +26,8 @@ StdPrs_ShadedShape.cxx
StdPrs_ShadedShape.hxx
StdPrs_ShadedSurface.cxx
StdPrs_ShadedSurface.hxx
StdPrs_ShapeTool.cxx
StdPrs_ShapeTool.hxx
StdPrs_ToolPoint.cxx
StdPrs_ToolPoint.hxx
StdPrs_ToolRFace.cxx

View File

@@ -0,0 +1,650 @@
// Created on: 2013-09-16
// Copyright (c) 2013-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 <StdPrs_BRepFont.hxx>
#include <BRep_Tool.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepLib_MakeEdge.hxx>
#include <Font_FTLibrary.hxx>
#include <Font_FontMgr.hxx>
#include <Font_TextFormatter.hxx>
#include <GCE2d_MakeSegment.hxx>
#include <GC_MakeSegment.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom_Plane.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2d_Line.hxx>
#include <GeomAPI.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomLib.hxx>
#include <gp_Pln.hxx>
#include <TColGeom2d_HSequenceOfBoundedCurve.hxx>
#include <TCollection_AsciiString.hxx>
#include <TCollection_HAsciiString.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
IMPLEMENT_STANDARD_RTTIEXT(StdPrs_BRepFont, Font_FTFont)
namespace
{
// pre-defined font rendering options
static const unsigned int THE_FONT_SIZE = 72;
static const unsigned int THE_RESOLUTION_DPI = 4800;
static const Font_FTFontParams THE_FONT_PARAMS (THE_FONT_SIZE, THE_RESOLUTION_DPI);
// compute scaling factor for specified font size
inline Standard_Real getScale (const Standard_Real theSize)
{
return theSize / Standard_Real(THE_FONT_SIZE) * 72.0 / Standard_Real(THE_RESOLUTION_DPI);
}
//! Auxiliary method to convert FT_Vector to gp_XY
static gp_XY readFTVec (const FT_Vector& theVec,
const Standard_Real theScaleUnits,
const Standard_Real theWidthScaling = 1.0)
{
return gp_XY (theScaleUnits * Standard_Real(theVec.x) * theWidthScaling / 64.0, theScaleUnits * Standard_Real(theVec.y) / 64.0);
}
//! Auxiliary method for classification wire theW2 with respect to wire theW1
static TopAbs_State classifyWW (const TopoDS_Wire& theW1,
const TopoDS_Wire& theW2,
const TopoDS_Face& theF)
{
TopAbs_State aRes = TopAbs_UNKNOWN;
TopoDS_Face aF = TopoDS::Face (theF.EmptyCopied());
aF.Orientation (TopAbs_FORWARD);
BRep_Builder aB;
aB.Add (aF, theW1);
BRepTopAdaptor_FClass2d aClass2d (aF, ::Precision::PConfusion());
for (TopoDS_Iterator anEdgeIter (theW2); anEdgeIter.More(); anEdgeIter.Next())
{
const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Value());
Standard_Real aPFirst = 0.0, aPLast = 0.0;
Handle(Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface (anEdge, theF, aPFirst, aPLast);
if (aCurve2d.IsNull())
{
continue;
}
gp_Pnt2d aPnt2d = aCurve2d->Value ((aPFirst + aPLast) / 2.0);
TopAbs_State aState = aClass2d.Perform (aPnt2d, Standard_False);
if (aState == TopAbs_OUT
|| aState == TopAbs_IN)
{
if (aRes == TopAbs_UNKNOWN)
{
aRes = aState;
}
else if (aRes != aState)
{
return TopAbs_UNKNOWN;
}
}
}
return aRes;
}
}
// =======================================================================
// function : Constructor
// purpose :
// =======================================================================
StdPrs_BRepFont::StdPrs_BRepFont ()
: myPrecision (Precision::Confusion()),
myScaleUnits (1.0),
myIsCompositeCurve (Standard_False),
my3Poles (1, 3),
my4Poles (1, 4)
{
init();
}
// =======================================================================
// function : init
// purpose :
// =======================================================================
void StdPrs_BRepFont::init()
{
mySurface = new Geom_Plane (gp_Pln (gp::XOY()));
myCurve2dAdaptor = new Geom2dAdaptor_HCurve();
Handle(Adaptor3d_HSurface) aSurfAdaptor = new GeomAdaptor_HSurface (mySurface);
myCurvOnSurf.Load (aSurfAdaptor);
}
// =======================================================================
// function : Constructor
// purpose :
// =======================================================================
StdPrs_BRepFont::StdPrs_BRepFont (const NCollection_String& theFontPath,
const Standard_Real theSize,
const Standard_Integer theFaceId)
: myPrecision (Precision::Confusion()),
myScaleUnits (1.0),
myIsCompositeCurve (Standard_False),
my3Poles (1, 3),
my4Poles (1, 4)
{
init();
if (theSize <= myPrecision * 100.0)
{
return;
}
myScaleUnits = getScale (theSize);
Font_FTFont::Init (theFontPath.ToCString(), THE_FONT_PARAMS, theFaceId);
}
// =======================================================================
// function : Constructor
// purpose :
// =======================================================================
StdPrs_BRepFont::StdPrs_BRepFont (const NCollection_String& theFontName,
const Font_FontAspect theFontAspect,
const Standard_Real theSize,
const Font_StrictLevel theStrictLevel)
: myPrecision (Precision::Confusion()),
myScaleUnits (1.0),
myIsCompositeCurve (Standard_False),
my3Poles (1, 3),
my4Poles (1, 4)
{
init();
if (theSize <= myPrecision * 100.0)
{
return;
}
myScaleUnits = getScale (theSize);
Font_FTFont::FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel);
}
// =======================================================================
// function : Release
// purpose :
// =======================================================================
void StdPrs_BRepFont::Release()
{
myCache.Clear();
Font_FTFont::Release();
}
// =======================================================================
// function : SetCompositeCurveMode
// purpose :
// =======================================================================
void StdPrs_BRepFont::SetCompositeCurveMode (const Standard_Boolean theToConcatenate)
{
if (myIsCompositeCurve != theToConcatenate)
{
myIsCompositeCurve = theToConcatenate;
myCache.Clear();
}
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
bool StdPrs_BRepFont::Init (const NCollection_String& theFontPath,
const Standard_Real theSize,
const Standard_Integer theFaceId)
{
if (theSize <= myPrecision * 100.0)
{
return false;
}
myScaleUnits = getScale (theSize);
return Font_FTFont::Init (theFontPath.ToCString(), THE_FONT_PARAMS, theFaceId);
}
// =======================================================================
// function : FindAndInit
// purpose :
// =======================================================================
bool StdPrs_BRepFont::FindAndInit (const TCollection_AsciiString& theFontName,
const Font_FontAspect theFontAspect,
const Standard_Real theSize,
const Font_StrictLevel theStrictLevel)
{
if (theSize <= myPrecision * 100.0)
{
return false;
}
myScaleUnits = getScale (theSize);
return Font_FTFont::FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel);
}
// =======================================================================
// function : RenderGlyph
// purpose :
// =======================================================================
TopoDS_Shape StdPrs_BRepFont::RenderGlyph (const Standard_Utf32Char& theChar)
{
TopoDS_Shape aShape;
Standard_Mutex::Sentry aSentry (myMutex);
renderGlyph (theChar, aShape);
return aShape;
}
// =======================================================================
// function : to3d
// purpose :
// =======================================================================
bool StdPrs_BRepFont::to3d (const Handle(Geom2d_Curve)& theCurve2d,
const GeomAbs_Shape theContinuity,
Handle(Geom_Curve)& theCurve3d)
{
Standard_Real aMaxDeviation = 0.0;
Standard_Real anAverDeviation = 0.0;
myCurve2dAdaptor->ChangeCurve2d().Load (theCurve2d);
const Handle(Adaptor2d_HCurve2d)& aCurve = myCurve2dAdaptor; // to avoid ambiguity
myCurvOnSurf.Load (aCurve);
GeomLib::BuildCurve3d (myPrecision, myCurvOnSurf,
myCurve2dAdaptor->FirstParameter(), myCurve2dAdaptor->LastParameter(),
theCurve3d, aMaxDeviation, anAverDeviation, theContinuity);
return !theCurve3d.IsNull();
}
// =======================================================================
// function : buildFaces
// purpose :
// =======================================================================
Standard_Boolean StdPrs_BRepFont::buildFaces (const NCollection_Sequence<TopoDS_Wire>& theWires,
TopoDS_Shape& theRes)
{
// classify wires
NCollection_DataMap<TopoDS_Shape, NCollection_Sequence<TopoDS_Wire>, TopTools_ShapeMapHasher> aMapOutInts;
TopTools_DataMapOfShapeInteger aMapNbOuts;
TopoDS_Face aF;
myBuilder.MakeFace (aF, mySurface, myPrecision);
Standard_Integer aWireIter1Index = 1;
for (NCollection_Sequence<TopoDS_Wire>::Iterator aWireIter1 (theWires); aWireIter1.More(); ++aWireIter1Index, aWireIter1.Next())
{
const TopoDS_Wire& aW1 = aWireIter1.Value();
if (!aMapNbOuts.IsBound (aW1))
{
const Standard_Integer aNbOuts = 0;
aMapNbOuts.Bind (aW1, aNbOuts);
}
NCollection_Sequence<TopoDS_Wire>* anIntWs = aMapOutInts.Bound (aW1, NCollection_Sequence<TopoDS_Wire>());
Standard_Integer aWireIter2Index = 1;
for (NCollection_Sequence<TopoDS_Wire>::Iterator aWireIter2 (theWires); aWireIter2.More(); ++aWireIter2Index, aWireIter2.Next())
{
if (aWireIter1Index == aWireIter2Index)
{
continue;
}
const TopoDS_Wire& aW2 = aWireIter2.Value();
const TopAbs_State aClass = classifyWW (aW1, aW2, aF);
if (aClass == TopAbs_IN)
{
anIntWs->Append (aW2);
if (Standard_Integer* aNbOutsPtr = aMapNbOuts.ChangeSeek (aW2))
{
++(*aNbOutsPtr);
}
else
{
const Standard_Integer aNbOuts = 1;
aMapNbOuts.Bind (aW2, aNbOuts);
}
}
}
}
// check out wires and remove "not out" wires from maps
for (TopTools_DataMapIteratorOfDataMapOfShapeInteger anOutIter (aMapNbOuts); anOutIter.More(); anOutIter.Next())
{
const Standard_Integer aTmp = anOutIter.Value() % 2;
if (aTmp > 0)
{
// not out wire
aMapOutInts.UnBind (anOutIter.Key());
}
}
// create faces for out wires
TopTools_MapOfShape anUsedShapes;
TopoDS_Compound aFaceComp;
myBuilder.MakeCompound (aFaceComp);
for (; !aMapOutInts.IsEmpty(); )
{
// find out wire with max number of outs
TopoDS_Shape aW;
Standard_Integer aMaxNbOuts = -1;
for (NCollection_DataMap<TopoDS_Shape, NCollection_Sequence<TopoDS_Wire>, TopTools_ShapeMapHasher>::Iterator itMOI (aMapOutInts);
itMOI.More(); itMOI.Next())
{
const TopoDS_Shape& aKey = itMOI.Key();
const Standard_Integer aNbOuts = aMapNbOuts.Find (aKey);
if (aNbOuts > aMaxNbOuts)
{
aMaxNbOuts = aNbOuts;
aW = aKey;
}
}
// create face for selected wire
TopoDS_Face aNewF;
myBuilder.MakeFace (aNewF, mySurface, myPrecision);
myBuilder.Add (aNewF, aW);
anUsedShapes.Add (aW);
const NCollection_Sequence<TopoDS_Wire>& anIns = aMapOutInts.Find (aW);
for (NCollection_Sequence<TopoDS_Wire>::Iterator aWireIter (anIns); aWireIter.More(); aWireIter.Next())
{
TopoDS_Wire aWin = aWireIter.Value();
if (anUsedShapes.Contains (aWin))
{
continue;
}
aWin.Reverse();
myBuilder.Add (aNewF, aWin);
anUsedShapes.Add (aWin);
}
myBuilder.Add (aFaceComp, aNewF);
aMapOutInts.UnBind (aW);
}
if (aFaceComp.NbChildren() == 0)
{
return Standard_False;
}
if (aFaceComp.NbChildren() == 1)
{
theRes = TopoDS_Iterator (aFaceComp).Value();
}
else
{
theRes = aFaceComp;
}
return Standard_True;
}
// =======================================================================
// function : renderGlyph
// purpose :
// =======================================================================
Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
TopoDS_Shape& theShape)
{
theShape.Nullify();
if (!loadGlyph (theChar)
|| myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
{
return Standard_False;
}
else if (myCache.Find (theChar, theShape))
{
return !theShape.IsNull();
}
const FT_Outline& anOutline = myActiveFTFace->glyph->outline;
if (!anOutline.n_contours)
return Standard_False;
TopLoc_Location aLoc;
NCollection_Sequence<TopoDS_Wire> aWires;
TopoDS_Compound aFaceCompDraft;
// Get orientation is useless since it doesn't retrieve any in-font information and just computes orientation.
// Because it fails in some cases - leave this to ShapeFix.
//const FT_Orientation anOrient = FT_Outline_Get_Orientation (&anOutline);
for (short aContour = 0, aStartIndex = 0; aContour < anOutline.n_contours; ++aContour)
{
const FT_Vector* aPntList = &anOutline.points[aStartIndex];
const char* aTags = &anOutline.tags[aStartIndex];
const short anEndIndex = anOutline.contours[aContour];
const short aPntsNb = (anEndIndex - aStartIndex) + 1;
aStartIndex = anEndIndex + 1;
if (aPntsNb < 3 && !myFontParams.IsSingleStrokeFont)
{
// closed contour can not be constructed from < 3 points
continue;
}
BRepBuilderAPI_MakeWire aWireMaker;
gp_XY aPntPrev;
gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits, myWidthScaling);
gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits, myWidthScaling);
bool isLineSeg = !myFontParams.IsSingleStrokeFont
&& FT_CURVE_TAG(aTags[aPntsNb - 1]) == FT_Curve_Tag_On;
gp_XY aPntLine1 = aPntCurr;
// see http://freetype.sourceforge.net/freetype2/docs/glyphs/glyphs-6.html
// for a full description of FreeType tags.
for (short aPntId = 0; aPntId < aPntsNb; ++aPntId)
{
aPntPrev = aPntCurr;
aPntCurr = aPntNext;
aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits, myWidthScaling);
// process tags
if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_On)
{
if (!isLineSeg)
{
aPntLine1 = aPntCurr;
isLineSeg = true;
continue;
}
const gp_XY aDirVec = aPntCurr - aPntLine1;
const Standard_Real aLen = aDirVec.Modulus();
if (aLen <= myPrecision)
{
aPntLine1 = aPntCurr;
isLineSeg = true;
continue;
}
if (myIsCompositeCurve)
{
Handle(Geom2d_TrimmedCurve) aLine = GCE2d_MakeSegment (gp_Pnt2d (aPntLine1), gp_Pnt2d (aPntCurr));
myConcatMaker.Add (aLine, myPrecision);
}
else
{
Handle(Geom_Curve) aCurve3d;
Handle(Geom2d_Line) aCurve2d = new Geom2d_Line (gp_Pnt2d (aPntLine1), gp_Dir2d (aDirVec));
if (to3d (aCurve2d, GeomAbs_C1, aCurve3d))
{
TopoDS_Edge anEdge = BRepLib_MakeEdge (aCurve3d, 0.0, aLen);
myBuilder.UpdateEdge (anEdge, aCurve2d, mySurface, aLoc, myPrecision);
aWireMaker.Add (anEdge);
}
}
aPntLine1 = aPntCurr;
}
else if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_Conic)
{
isLineSeg = false;
gp_XY aPntPrev2 = aPntPrev;
gp_XY aPntNext2 = aPntNext;
// previous point is either the real previous point (an "on" point),
// or the midpoint between the current one and the previous "conic off" point
if (FT_CURVE_TAG(aTags[(aPntId - 1 + aPntsNb) % aPntsNb]) == FT_Curve_Tag_Conic)
{
aPntPrev2 = (aPntCurr + aPntPrev) * 0.5;
}
// next point is either the real next point or the midpoint
if (FT_CURVE_TAG(aTags[(aPntId + 1) % aPntsNb]) == FT_Curve_Tag_Conic)
{
aPntNext2 = (aPntCurr + aPntNext) * 0.5;
}
my3Poles.SetValue (1, aPntPrev2);
my3Poles.SetValue (2, aPntCurr);
my3Poles.SetValue (3, aPntNext2);
Handle(Geom2d_BezierCurve) aBezierArc = new Geom2d_BezierCurve (my3Poles);
if (myIsCompositeCurve)
{
myConcatMaker.Add (aBezierArc, myPrecision);
}
else
{
Handle(Geom_Curve) aCurve3d;
if (to3d (aBezierArc, GeomAbs_C1, aCurve3d))
{
TopoDS_Edge anEdge = BRepLib_MakeEdge (aCurve3d);
myBuilder.UpdateEdge (anEdge, aBezierArc, mySurface, aLoc, myPrecision);
aWireMaker.Add (anEdge);
}
}
}
else if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_Cubic
&& FT_CURVE_TAG(aTags[(aPntId + 1) % aPntsNb]) == FT_Curve_Tag_Cubic)
{
isLineSeg = false;
my4Poles.SetValue (1, aPntPrev);
my4Poles.SetValue (2, aPntCurr);
my4Poles.SetValue (3, aPntNext);
my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits, myWidthScaling)));
Handle(Geom2d_BezierCurve) aBezier = new Geom2d_BezierCurve (my4Poles);
if (myIsCompositeCurve)
{
myConcatMaker.Add (aBezier, myPrecision);
}
else
{
Handle(Geom_Curve) aCurve3d;
if (to3d (aBezier, GeomAbs_C1, aCurve3d))
{
TopoDS_Edge anEdge = BRepLib_MakeEdge (aCurve3d);
myBuilder.UpdateEdge (anEdge, aBezier, mySurface, aLoc, myPrecision);
aWireMaker.Add (anEdge);
}
}
}
}
if (myIsCompositeCurve)
{
Handle(Geom2d_BSplineCurve) aDraft2d = myConcatMaker.BSplineCurve();
if (aDraft2d.IsNull())
{
continue;
}
const gp_Pnt2d aFirstPnt = aDraft2d->StartPoint();
const gp_Pnt2d aLastPnt = aDraft2d->EndPoint();
if (!myFontParams.IsSingleStrokeFont
&& !aFirstPnt.IsEqual (aLastPnt, myPrecision))
{
Handle(Geom2d_TrimmedCurve) aLine = GCE2d_MakeSegment (aLastPnt, aFirstPnt);
myConcatMaker.Add (aLine, myPrecision);
}
Handle(Geom2d_BSplineCurve) aCurve2d = myConcatMaker.BSplineCurve();
Handle(Geom_Curve) aCurve3d;
if (to3d (aCurve2d, GeomAbs_C0, aCurve3d))
{
TopoDS_Edge anEdge = BRepLib_MakeEdge (aCurve3d);
myBuilder.UpdateEdge (anEdge, aCurve2d, mySurface, aLoc, myPrecision);
aWireMaker.Add (anEdge);
}
myConcatMaker.Clear();
}
else
{
if (!aWireMaker.IsDone())
{
continue;
}
TopoDS_Vertex aFirstV, aLastV;
TopExp::Vertices (aWireMaker.Wire(), aFirstV, aLastV);
gp_Pnt aFirstPoint = BRep_Tool::Pnt (aFirstV);
gp_Pnt aLastPoint = BRep_Tool::Pnt (aLastV);
if (!myFontParams.IsSingleStrokeFont
&& !aFirstPoint.IsEqual (aLastPoint, myPrecision))
{
aWireMaker.Add (BRepLib_MakeEdge (aFirstV, aLastV));
}
}
if (!aWireMaker.IsDone())
{
continue;
}
TopoDS_Wire aWireDraft = aWireMaker.Wire();
if (!myFontParams.IsSingleStrokeFont)
{
// collect all wires and set CCW orientation
TopoDS_Face aFace;
myBuilder.MakeFace (aFace, mySurface, myPrecision);
myBuilder.Add (aFace, aWireDraft);
BRepTopAdaptor_FClass2d aClass2d (aFace, ::Precision::PConfusion());
TopAbs_State aState = aClass2d.PerformInfinitePoint();
if (aState != TopAbs_OUT)
{
// need to reverse
aWireDraft.Reverse();
}
aWires.Append (aWireDraft);
}
else
{
if (aFaceCompDraft.IsNull())
{
myBuilder.MakeCompound (aFaceCompDraft);
}
myBuilder.Add (aFaceCompDraft, aWireDraft);
}
}
if (!aWires.IsEmpty())
{
buildFaces (aWires, theShape);
}
else if (!aFaceCompDraft.IsNull())
{
theShape = aFaceCompDraft;
}
myCache.Bind (theChar, theShape);
return !theShape.IsNull();
}

View File

@@ -0,0 +1,244 @@
// Created on: 2013-09-16
// Copyright (c) 2013-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.
#ifndef _StdPrs_BRepFont_H__
#define _StdPrs_BRepFont_H__
#include <Adaptor3d_CurveOnSurface.hxx>
#include <BRep_Builder.hxx>
#include <Font_FTFont.hxx>
#include <Font_TextFormatter.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
#include <gp_Ax3.hxx>
#include <gp_XY.hxx>
#include <gp_XYZ.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_String.hxx>
#include <Standard_Mutex.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Face.hxx>
#include <TopTools_SequenceOfShape.hxx>
DEFINE_STANDARD_HANDLE(StdPrs_BRepFont, Font_FTFont)
//! This tool provides basic services for rendering of vectorized text glyphs as BRep shapes.
//! Single instance initialize single font for sequential glyphs rendering with implicit caching of already rendered glyphs.
//! Thus position of each glyph in the text is specified by shape location.
//!
//! Please notice that this implementation uses mutex for thread-safety access,
//! thus may lead to performance penalties in case of concurrent access.
//! Although caching should eliminate this issue after rendering of sufficient number of glyphs.
class StdPrs_BRepFont : protected Font_FTFont
{
DEFINE_STANDARD_RTTIEXT(StdPrs_BRepFont, Font_FTFont)
public:
//! Empty constructor
Standard_EXPORT StdPrs_BRepFont();
//! Constructor with initialization.
//! @param theFontPath FULL path to the font
//! @param theSize the face size in model units
//! @param theFaceId face id within the file (0 by default)
Standard_EXPORT StdPrs_BRepFont (const NCollection_String& theFontPath,
const Standard_Real theSize,
const Standard_Integer theFaceId = 0);
//! Constructor with initialization.
//! @param theFontName the font name
//! @param theFontAspect the font style
//! @param theSize the face size in model units
//! @param theStrictLevel search strict level for using aliases and fallback
Standard_EXPORT StdPrs_BRepFont (const NCollection_String& theFontName,
const Font_FontAspect theFontAspect,
const Standard_Real theSize,
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
//! Release currently loaded font.
Standard_EXPORT virtual void Release() Standard_OVERRIDE;
//! Initialize the font.
//! @param theFontPath FULL path to the font
//! @param theSize the face size in model units
//! @param theFaceId face id within the file (0 by default)
//! @return true on success
Standard_EXPORT bool Init (const NCollection_String& theFontPath,
const Standard_Real theSize,
const Standard_Integer theFaceId);
//! Find (using Font_FontMgr) and initialize the font from the given name.
//! Please take into account that size is specified NOT in typography points (pt.).
//! If you need to specify size in points, value should be converted.
//! Formula for pt. -> m conversion:
//! aSizeMeters = 0.0254 * theSizePt / 72.0
//! @param theFontName the font name
//! @param theFontAspect the font style
//! @param theSize the face size in model units
//! @param theStrictLevel search strict level for using aliases and fallback
//! @return true on success
Standard_EXPORT bool FindAndInit (const TCollection_AsciiString& theFontName,
const Font_FontAspect theFontAspect,
const Standard_Real theSize,
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
//! Render single glyph as TopoDS_Shape.
//! @param theChar glyph identifier
//! @return rendered glyph within cache, might be NULL shape
Standard_EXPORT TopoDS_Shape RenderGlyph (const Standard_Utf32Char& theChar);
//! Setup glyph geometry construction mode.
//! By default algorithm creates independent TopoDS_Edge
//! for each original curve in the glyph (line segment or Bezie curve).
//! Algorithm might optionally create composite BSpline curve for each contour
//! which reduces memory footprint but limits curve class to C0.
//! Notice that altering this flag clears currently accumulated cache!
Standard_EXPORT void SetCompositeCurveMode (const Standard_Boolean theToConcatenate);
//! Setup glyph scaling along X-axis.
//! By default glyphs are not scaled (scaling factor = 1.0)
void SetWidthScaling (const float theScaleFactor)
{
myWidthScaling = theScaleFactor;
}
public:
//! @return vertical distance from the horizontal baseline to the highest character coordinate.
Standard_Real Ascender() const
{
return myScaleUnits * Standard_Real(Font_FTFont::Ascender());
}
//! @return vertical distance from the horizontal baseline to the lowest character coordinate.
Standard_Real Descender() const
{
return myScaleUnits * Standard_Real(Font_FTFont::Descender());
}
//! @return default line spacing (the baseline-to-baseline distance).
Standard_Real LineSpacing() const
{
return myScaleUnits * Standard_Real(Font_FTFont::LineSpacing());
}
//! Configured point size
Standard_Real PointSize() const
{
return myScaleUnits * Standard_Real(Font_FTFont::PointSize());
}
//! Compute advance to the next character with kerning applied when applicable.
//! Assuming text rendered horizontally.
Standard_Real AdvanceX (const Standard_Utf32Char theUCharNext)
{
return myScaleUnits * Standard_Real(Font_FTFont::AdvanceX (theUCharNext));
}
//! Compute advance to the next character with kerning applied when applicable.
//! Assuming text rendered horizontally.
Standard_Real AdvanceX (const Standard_Utf32Char theUChar,
const Standard_Utf32Char theUCharNext)
{
return myScaleUnits * Standard_Real(Font_FTFont::AdvanceX (theUChar, theUCharNext));
}
//! Compute advance to the next character with kerning applied when applicable.
//! Assuming text rendered vertically.
Standard_Real AdvanceY (const Standard_Utf32Char theUCharNext)
{
return myScaleUnits * Standard_Real(Font_FTFont::AdvanceY (theUCharNext));
}
//! Compute advance to the next character with kerning applied when applicable.
//! Assuming text rendered vertically.
Standard_Real AdvanceY (const Standard_Utf32Char theUChar,
const Standard_Utf32Char theUCharNext)
{
return myScaleUnits * Standard_Real(Font_FTFont::AdvanceY (theUChar, theUCharNext));
}
//! Returns scaling factor for current font size.
Standard_Real Scale() const
{
return myScaleUnits;
}
//! Returns mutex.
Standard_Mutex& Mutex()
{
return myMutex;
}
public:
//! Find (using Font_FontMgr) and initialize the font from the given name.
//! Alias for FindAndInit() for backward compatibility.
bool Init (const NCollection_String& theFontName,
const Font_FontAspect theFontAspect,
const Standard_Real theSize)
{
return FindAndInit (theFontName.ToCString(), theFontAspect, theSize, Font_StrictLevel_Any);
}
protected:
//! Render single glyph as TopoDS_Shape. This method does not lock the mutex.
//! @param theChar glyph identifier
//! @param theShape rendered glyph within cache, might be NULL shape
//! @return true if glyph's geometry is available
Standard_EXPORT Standard_Boolean renderGlyph (const Standard_Utf32Char theChar,
TopoDS_Shape& theShape);
private:
//! Initialize class fields
void init();
//! Auxiliary method to create 3D curve
bool to3d (const Handle(Geom2d_Curve)& theCurve2d,
const GeomAbs_Shape theContinuity,
Handle(Geom_Curve)& theCurve3d);
//! Auxiliary method for creation faces from sequence of wires.
//! Splits to few faces (if it is needed) and updates orientation of wires.
Standard_Boolean buildFaces (const NCollection_Sequence<TopoDS_Wire>& theWires,
TopoDS_Shape& theRes);
//! Hide visibility.
using Font_FTFont::FindAndCreate;
protected: //! @name Protected fields
NCollection_DataMap<Standard_Utf32Char, TopoDS_Shape>
myCache; //!< glyphs cache
Standard_Mutex myMutex; //!< lock for thread-safety
Handle(Geom_Surface) mySurface; //!< surface to place glyphs on to
Standard_Real myPrecision; //!< algorithm precision
Standard_Real myScaleUnits; //!< scale font rendering units into model units
Standard_Boolean myIsCompositeCurve; //!< flag to merge C1 curves of each contour into single C0 curve, OFF by default
protected: //! @name Shared temporary variables for glyph construction
Adaptor3d_CurveOnSurface myCurvOnSurf;
Handle(Geom2dAdaptor_HCurve) myCurve2dAdaptor;
Geom2dConvert_CompCurveToBSplineCurve myConcatMaker;
TColgp_Array1OfPnt2d my3Poles;
TColgp_Array1OfPnt2d my4Poles;
BRep_Builder myBuilder;
};
#endif // _StdPrs_BRepFont_H__

View File

@@ -0,0 +1,89 @@
// Created on: 2015-08-10
// Created by: Ilya SEVRIKOV
// Copyright (c) 2013-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 <StdPrs_BRepTextBuilder.hxx>
// =======================================================================
// Function : Perfrom
// Purpose :
// =======================================================================
TopoDS_Shape StdPrs_BRepTextBuilder::Perform (StdPrs_BRepFont& theFont,
const Font_TextFormatter& theFormatter,
const gp_Ax3& thePenLoc)
{
gp_Trsf aTrsf;
gp_XYZ aPen;
TopoDS_Shape aGlyphShape;
TopoDS_Compound aResult;
Standard_Mutex::Sentry aSentry (theFont.Mutex());
myBuilder.MakeCompound (aResult);
Standard_Integer aSymbolCounter = 0;
Standard_Real aScaleUnits = theFont.Scale();
for (NCollection_Utf8Iter anIter = theFormatter.String().Iterator(); *anIter != 0; ++anIter)
{
const Standard_Utf32Char aCharCurr = *anIter;
if (aCharCurr == '\x0D' // CR (carriage return)
|| aCharCurr == '\a' // BEL (alarm)
|| aCharCurr == '\f' // FF (form feed) NP (new page)
|| aCharCurr == '\b' // BS (backspace)
|| aCharCurr == '\v' // VT (vertical tab)
|| aCharCurr == ' '
|| aCharCurr == '\t'
|| aCharCurr == '\n')
{
continue; // skip unsupported carriage control codes
}
const NCollection_Vec2<Standard_ShortReal>& aCorner = theFormatter.TopLeft (aSymbolCounter);
aPen.SetCoord (aCorner.x() * aScaleUnits, aCorner.y() * aScaleUnits, 0.0);
aGlyphShape = theFont.RenderGlyph (aCharCurr);
if (!aGlyphShape.IsNull())
{
aTrsf.SetTranslation (gp_Vec (aPen));
aGlyphShape.Move (aTrsf);
myBuilder.Add (aResult, aGlyphShape);
}
++aSymbolCounter;
}
aTrsf.SetTransformation (thePenLoc, gp_Ax3 (gp::XOY()));
aResult.Move (aTrsf);
return aResult;
}
// =======================================================================
// Function : Perform
// Purpose :
// =======================================================================
TopoDS_Shape StdPrs_BRepTextBuilder::Perform (StdPrs_BRepFont& theFont,
const NCollection_String& theString,
const gp_Ax3& thePenLoc,
const Graphic3d_HorizontalTextAlignment theHAlign,
const Graphic3d_VerticalTextAlignment theVAlign)
{
Font_TextFormatter aFormatter;
aFormatter.Reset();
aFormatter.SetupAlignment (theHAlign, theVAlign);
aFormatter.Append (theString, *(reinterpret_cast<Font_FTFont*> (&theFont)));
aFormatter.Format();
return Perform (theFont, aFormatter, thePenLoc);
}

View File

@@ -0,0 +1,51 @@
// Created on: 2015-08-10
// Created by: Ilya SEVRIKOV
// Copyright (c) 2013-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.
#ifndef StdPrs_BRepTextBuilder_Header
#define StdPrs_BRepTextBuilder_Header
#include <Font_BRepFont.hxx>
#include <Font_TextFormatter.hxx>
#include <gp_Ax3.hxx>
//! Represents class for applying text formatting.
class StdPrs_BRepTextBuilder
{
public:
//! Render text as BRep shape.
//! @param theString text in UTF-8 encoding
//! @param thePenLoc start position and orientation on the baseline
//! @param theFormatter formatter which defines alignment for the text
//! @return result shape with pen transformation applied as shape location
Standard_EXPORT TopoDS_Shape Perform (StdPrs_BRepFont& theFont,
const Font_TextFormatter& theFormatter,
const gp_Ax3& thePenLoc = gp_Ax3());
//! Render text as BRep shape.
//! @param theString text in UTF-8 encoding
//! @param thePenLoc start position and orientation on the baseline
//! @param theHAlign horizontal alignment of the text
//! @param theVAlign vertical alignment of the text
//! @return result shape with pen transformation applied as shape location
Standard_EXPORT TopoDS_Shape Perform (StdPrs_BRepFont& theFont,
const NCollection_String& theString,
const gp_Ax3& thePenLoc = gp_Ax3(),
const Graphic3d_HorizontalTextAlignment theHAlign = Graphic3d_HTA_LEFT,
const Graphic3d_VerticalTextAlignment theVAlign = Graphic3d_VTA_BOTTOM);
protected:
BRep_Builder myBuilder;
};
#endif // StdPrs_BRepTextBuilder_Header

View File

@@ -1,54 +0,0 @@
// Created on: 2014-10-14
// Created by: Anton POLETAEV
// Copyright (c) 2013-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 <StdPrs_BndBox.hxx>
#include <Prs3d_LineAspect.hxx>
//=======================================================================
//function : Add
//purpose :
//=======================================================================
void StdPrs_BndBox::Add (const Handle(Prs3d_Presentation)& thePresentation,
const Bnd_Box& theBndBox,
const Handle(Prs3d_Drawer)& theDrawer)
{
if (!theBndBox.IsVoid())
{
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (theDrawer->LineAspect()->Aspect()->Color(),
Aspect_TOL_DOTDASH,
theDrawer->LineAspect()->Aspect()->Width()));
aGroup->AddPrimitiveArray (FillSegments (theBndBox));
}
}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
void StdPrs_BndBox::Add (const Handle(Prs3d_Presentation)& thePresentation,
const Bnd_OBB& theBndBox,
const Handle(Prs3d_Drawer)& theDrawer)
{
if (!theBndBox.IsVoid())
{
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (theDrawer->LineAspect()->Aspect()->Color(),
Aspect_TOL_DOTDASH,
theDrawer->LineAspect()->Aspect()->Width()));
aGroup->AddPrimitiveArray (FillSegments (theBndBox));
}
}

View File

@@ -1,6 +1,4 @@
// Created on: 2014-10-14
// Created by: Anton POLETAEV
// Copyright (c) 2013-2014 OPEN CASCADE SAS
// Copyright (c) 2020 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
@@ -16,133 +14,8 @@
#ifndef _StdPrs_BndBox_H__
#define _StdPrs_BndBox_H__
#include <Bnd_OBB.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Graphic3d_ArrayOfTriangles.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_Presentation.hxx>
#include <Prs3d_Root.hxx>
#include <Prs3d_BndBox.hxx>
//! Tool for computing bounding box presentation.
class StdPrs_BndBox : public Prs3d_Root
{
public:
//! Computes presentation of a bounding box.
//! @param thePresentation [in] the presentation.
//! @param theBndBox [in] the bounding box.
//! @param theDrawer [in] the drawer.
Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation,
const Bnd_Box& theBndBox,
const Handle(Prs3d_Drawer)& theDrawer);
//! Computes presentation of a bounding box.
//! @param thePresentation [in] the presentation.
//! @param theBndBox [in] the bounding box.
//! @param theDrawer [in] the drawer.
Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation,
const Bnd_OBB& theBndBox,
const Handle(Prs3d_Drawer)& theDrawer);
public:
//! Create primitive array with line segments for displaying a box.
//! @param theBox [in] the box to add
static Handle(Graphic3d_ArrayOfSegments) FillSegments (const Bnd_OBB& theBox)
{
if (theBox.IsVoid())
{
return Handle(Graphic3d_ArrayOfSegments)();
}
Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments (8, 12 * 2);
FillSegments (aSegs, theBox);
return aSegs;
}
//! Create primitive array with line segments for displaying a box.
//! @param theBox [in] the box to add
static Handle(Graphic3d_ArrayOfSegments) FillSegments (const Bnd_Box& theBox)
{
if (theBox.IsVoid())
{
return Handle(Graphic3d_ArrayOfSegments)();
}
Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments (8, 12 * 2);
FillSegments (aSegs, theBox);
return aSegs;
}
//! Create primitive array with line segments for displaying a box.
//! @param theSegments [in] [out] primitive array to be filled;
//! should be at least 8 nodes and 24 edges in size
//! @param theBox [in] the box to add
static void FillSegments (const Handle(Graphic3d_ArrayOfSegments)& theSegments, const Bnd_OBB& theBox)
{
if (!theBox.IsVoid())
{
gp_Pnt aXYZ[8];
theBox.GetVertex (aXYZ);
fillSegments (theSegments, aXYZ);
}
}
//! Create primitive array with line segments for displaying a box.
//! @param theSegments [in] [out] primitive array to be filled;
//! should be at least 8 nodes and 24 edges in size
//! @param theBox [in] the box to add
static void FillSegments (const Handle(Graphic3d_ArrayOfSegments)& theSegments, const Bnd_Box& theBox)
{
if (!theBox.IsVoid())
{
const gp_Pnt aMin = theBox.CornerMin();
const gp_Pnt aMax = theBox.CornerMax();
const gp_Pnt aXYZ[8] =
{
gp_Pnt (aMin.X(), aMin.Y(), aMin.Z()),
gp_Pnt (aMax.X(), aMin.Y(), aMin.Z()),
gp_Pnt (aMin.X(), aMax.Y(), aMin.Z()),
gp_Pnt (aMax.X(), aMax.Y(), aMin.Z()),
gp_Pnt (aMin.X(), aMin.Y(), aMax.Z()),
gp_Pnt (aMax.X(), aMin.Y(), aMax.Z()),
gp_Pnt (aMin.X(), aMax.Y(), aMax.Z()),
gp_Pnt (aMax.X(), aMax.Y(), aMax.Z()),
};
fillSegments (theSegments, aXYZ);
}
}
public:
//! Create primitive array with line segments for displaying a box.
//! @param theSegments [in] [out] primitive array to be filled;
//! should be at least 8 nodes and 24 edges in size
//! @param theBox [in] the box to add
static void fillSegments (const Handle(Graphic3d_ArrayOfSegments)& theSegments, const gp_Pnt* theBox)
{
const Standard_Integer aFrom = theSegments->VertexNumber();
for (int aVertIter = 0; aVertIter < 8; ++aVertIter)
{
theSegments->AddVertex (theBox[aVertIter]);
}
theSegments->AddEdges (aFrom + 1, aFrom + 2);
theSegments->AddEdges (aFrom + 3, aFrom + 4);
theSegments->AddEdges (aFrom + 5, aFrom + 6);
theSegments->AddEdges (aFrom + 7, aFrom + 8);
//
theSegments->AddEdges (aFrom + 1, aFrom + 3);
theSegments->AddEdges (aFrom + 2, aFrom + 4);
theSegments->AddEdges (aFrom + 5, aFrom + 7);
theSegments->AddEdges (aFrom + 6, aFrom + 8);
//
theSegments->AddEdges (aFrom + 1, aFrom + 5);
theSegments->AddEdges (aFrom + 2, aFrom + 6);
theSegments->AddEdges (aFrom + 3, aFrom + 7);
theSegments->AddEdges (aFrom + 4, aFrom + 8);
}
};
typedef Prs3d_BndBox StdPrs_BndBox;
#endif // _StdPrs_BndBox_H__

View File

@@ -0,0 +1,200 @@
// Created on: 1995-08-07
// Created by: Modelistation
// Copyright (c) 1995-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 <StdPrs_ShapeTool.hxx>
#include <Bnd_Box.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepBndLib.hxx>
#include <BRepTools.hxx>
#include <Geom_Plane.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_Surface.hxx>
#include <Poly_Polygon3D.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Poly_Triangulation.hxx>
#include <TopExp.hxx>
#include <TopLoc_Location.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
//=======================================================================
//function : StdPrs_ShapeTool
//purpose :
//=======================================================================
StdPrs_ShapeTool::StdPrs_ShapeTool (const TopoDS_Shape& theShape,
const Standard_Boolean theAllVertices)
: myShape (theShape)
{
myEdgeMap.Clear();
myVertexMap.Clear();
TopExp::MapShapesAndAncestors (theShape,TopAbs_EDGE,TopAbs_FACE, myEdgeMap);
TopExp_Explorer anExpl;
if (theAllVertices)
{
for (anExpl.Init (theShape, TopAbs_VERTEX); anExpl.More(); anExpl.Next())
{
myVertexMap.Add (anExpl.Current());
}
}
else
{
// Extracting isolated vertices
for (anExpl.Init (theShape, TopAbs_VERTEX, TopAbs_EDGE); anExpl.More(); anExpl.Next())
{
myVertexMap.Add (anExpl.Current());
}
// Extracting internal vertices
for (anExpl.Init (theShape, TopAbs_EDGE); anExpl.More(); anExpl.Next())
{
TopoDS_Iterator aIt (anExpl.Current(), Standard_False, Standard_True);
for (; aIt.More(); aIt.Next())
{
const TopoDS_Shape& aV = aIt.Value();
if (aV.Orientation() == TopAbs_INTERNAL)
{
myVertexMap.Add (aV);
}
}
}
}
}
//=======================================================================
//function : FaceBound
//purpose :
//=======================================================================
Bnd_Box StdPrs_ShapeTool::FaceBound() const
{
const TopoDS_Face& F = TopoDS::Face(myFaceExplorer.Current());
Bnd_Box B;
BRepBndLib::Add(F, B);
return B;
}
//=======================================================================
//function : IsPlanarFace
//purpose :
//=======================================================================
Standard_Boolean StdPrs_ShapeTool::IsPlanarFace (const TopoDS_Face& theFace)
{
TopLoc_Location l;
const Handle(Geom_Surface)& S = BRep_Tool::Surface(theFace, l);
if (S.IsNull())
{
return Standard_False;
}
Handle(Standard_Type) TheType = S->DynamicType();
if (TheType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
Handle(Geom_RectangularTrimmedSurface)
RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S);
TheType = RTS->BasisSurface()->DynamicType();
}
return (TheType == STANDARD_TYPE(Geom_Plane));
}
//=======================================================================
//function : CurveBound
//purpose :
//=======================================================================
Bnd_Box StdPrs_ShapeTool::CurveBound() const
{
const TopoDS_Edge& E = TopoDS::Edge(myEdgeMap.FindKey(myEdge));
Bnd_Box B;
BRepBndLib::Add(E, B);
return B;
}
//=======================================================================
//function : Neighbours
//purpose :
//=======================================================================
Standard_Integer StdPrs_ShapeTool::Neighbours() const
{
const TopTools_ListOfShape& L = myEdgeMap.FindFromIndex(myEdge);
return L.Extent();
}
//=======================================================================
//function : FacesOfEdge
//purpose :
//=======================================================================
Handle(TopTools_HSequenceOfShape) StdPrs_ShapeTool::FacesOfEdge() const
{
Handle(TopTools_HSequenceOfShape) H = new TopTools_HSequenceOfShape();
const TopTools_ListOfShape& L = myEdgeMap.FindFromIndex(myEdge);
for (TopTools_ListIteratorOfListOfShape LI (L); LI.More(); LI.Next())
{
H->Append(LI.Value());
}
return H;
}
//=======================================================================
//function : HasSurface
//purpose :
//=======================================================================
Standard_Boolean StdPrs_ShapeTool::HasSurface() const
{
TopLoc_Location l;
const Handle(Geom_Surface)& S = BRep_Tool::Surface(GetFace(), l);
return !S.IsNull();
}
//=======================================================================
//function : CurrentTriangulation
//purpose :
//=======================================================================
Handle(Poly_Triangulation) StdPrs_ShapeTool::CurrentTriangulation(TopLoc_Location& l) const
{
return BRep_Tool::Triangulation(GetFace(), l);
}
//=======================================================================
//function : HasCurve
//purpose :
//=======================================================================
Standard_Boolean StdPrs_ShapeTool::HasCurve() const
{
return BRep_Tool::IsGeometric(GetCurve());
}
//=======================================================================
//function : PolygonOnTriangulation
//purpose :
//=======================================================================
void StdPrs_ShapeTool::PolygonOnTriangulation (Handle(Poly_PolygonOnTriangulation)& Indices,
Handle(Poly_Triangulation)& T,
TopLoc_Location& l) const
{
BRep_Tool::PolygonOnTriangulation(GetCurve(), Indices, T, l);
}
//=======================================================================
//function : Polygon3D
//purpose :
//=======================================================================
Handle(Poly_Polygon3D) StdPrs_ShapeTool::Polygon3D(TopLoc_Location& l) const
{
return BRep_Tool::Polygon3D(GetCurve(), l);
}

View File

@@ -0,0 +1,110 @@
// Created on: 1993-01-27
// Created by: Jean-Louis Frenkel
// Copyright (c) 1993-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.
#ifndef _StdPrs_ShapeTool_HeaderFile
#define _StdPrs_ShapeTool_HeaderFile
#include <Standard_DefineAlloc.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_HSequenceOfShape.hxx>
class Bnd_Box;
class Poly_Triangulation;
class Poly_PolygonOnTriangulation;
class Poly_Polygon3D;
//! Describes the behaviour requested for a wireframe shape presentation.
class StdPrs_ShapeTool
{
public:
DEFINE_STANDARD_ALLOC
//! Constructs the tool and initializes it using theShape and theAllVertices
//! (optional) arguments. By default, only isolated and internal vertices are considered,
//! however if theAllVertices argument is equal to True, all shape's vertices are taken into account.
Standard_EXPORT StdPrs_ShapeTool (const TopoDS_Shape& theShape, const Standard_Boolean theAllVertices = Standard_False);
void InitFace() { myFaceExplorer.Init(myShape,TopAbs_FACE); }
Standard_Boolean MoreFace() const { return myFaceExplorer.More(); }
void NextFace() { myFaceExplorer.Next(); }
const TopoDS_Face& GetFace() const { return TopoDS::Face(myFaceExplorer.Current()); }
Standard_EXPORT Bnd_Box FaceBound() const;
Standard_Boolean IsPlanarFace() const
{
const TopoDS_Face& aFace = TopoDS::Face (myFaceExplorer.Current());
return IsPlanarFace (aFace);
}
void InitCurve() { myEdge = 1; }
Standard_Boolean MoreCurve() const { return myEdge <= myEdgeMap.Extent(); }
void NextCurve() { ++myEdge; }
const TopoDS_Edge& GetCurve() const { return TopoDS::Edge(myEdgeMap.FindKey(myEdge)); }
Standard_EXPORT Bnd_Box CurveBound() const;
Standard_EXPORT Standard_Integer Neighbours() const;
Standard_EXPORT Handle(TopTools_HSequenceOfShape) FacesOfEdge() const;
void InitVertex() { myVertex = 1; }
Standard_Boolean MoreVertex() const { return myVertex <= myVertexMap.Extent(); }
void NextVertex() { ++myVertex; }
const TopoDS_Vertex& GetVertex() const { return TopoDS::Vertex (myVertexMap.FindKey(myVertex)); }
Standard_EXPORT Standard_Boolean HasSurface() const;
Standard_EXPORT Handle(Poly_Triangulation) CurrentTriangulation (TopLoc_Location& l) const;
Standard_EXPORT Standard_Boolean HasCurve() const;
Standard_EXPORT void PolygonOnTriangulation (Handle(Poly_PolygonOnTriangulation)& Indices, Handle(Poly_Triangulation)& T, TopLoc_Location& l) const;
Standard_EXPORT Handle(Poly_Polygon3D) Polygon3D (TopLoc_Location& l) const;
public:
Standard_EXPORT static Standard_Boolean IsPlanarFace (const TopoDS_Face& theFace);
private:
TopoDS_Shape myShape;
TopExp_Explorer myFaceExplorer;
TopTools_IndexedDataMapOfShapeListOfShape myEdgeMap;
TopTools_IndexedMapOfShape myVertexMap;
Standard_Integer myEdge;
Standard_Integer myVertex;
};
#endif // _StdPrs_ShapeTool_HeaderFile

View File

@@ -16,6 +16,7 @@
#include <StdPrs_ToolTriangulatedShape.hxx>
#include <BRepBndLib.hxx>
#include <BRepMesh_DiscretFactory.hxx>
#include <BRepMesh_DiscretRoot.hxx>
#include <BRepTools.hxx>
@@ -233,6 +234,39 @@ void StdPrs_ToolTriangulatedShape::Normal (const TopoDS_Face& theFace,
}
}
//=======================================================================
//function : GetDeflection
//purpose :
//=======================================================================
Standard_Real StdPrs_ToolTriangulatedShape::GetDeflection (const TopoDS_Shape& theShape,
const Handle(Prs3d_Drawer)& theDrawer)
{
if (theDrawer->TypeOfDeflection() != Aspect_TOD_RELATIVE)
{
return theDrawer->MaximalChordialDeviation();
}
Bnd_Box aBndBox;
BRepBndLib::Add (theShape, aBndBox, Standard_False);
if (aBndBox.IsVoid())
{
return theDrawer->MaximalChordialDeviation();
}
else if (aBndBox.IsOpen())
{
if (!aBndBox.HasFinitePart())
{
return theDrawer->MaximalChordialDeviation();
}
aBndBox = aBndBox.FinitePart();
}
// store computed relative deflection of shape as absolute deviation coefficient in case relative type to use it later on for sub-shapes
const Standard_Real aDeflection = Prs3d::GetDeflection (aBndBox, theDrawer->DeviationCoefficient(), theDrawer->MaximalChordialDeviation());
theDrawer->SetMaximalChordialDeviation (aDeflection);
return aDeflection;
}
//=======================================================================
//function : IsTessellated
//purpose :
@@ -240,7 +274,7 @@ void StdPrs_ToolTriangulatedShape::Normal (const TopoDS_Face& theFace,
Standard_Boolean StdPrs_ToolTriangulatedShape::IsTessellated (const TopoDS_Shape& theShape,
const Handle(Prs3d_Drawer)& theDrawer)
{
return BRepTools::Triangulation (theShape, Prs3d::GetDeflection (theShape, theDrawer), true);
return BRepTools::Triangulation (theShape, GetDeflection (theShape, theDrawer), true);
}
// =======================================================================
@@ -257,7 +291,7 @@ Standard_Boolean StdPrs_ToolTriangulatedShape::Tessellate (const TopoDS_Shape&
return wasRecomputed;
}
Standard_Real aDeflection = Prs3d::GetDeflection (theShape, theDrawer);
const Standard_Real aDeflection = GetDeflection (theShape, theDrawer);
// retrieve meshing tool from Factory
Handle(BRepMesh_DiscretRoot) aMeshAlgo = BRepMesh_DiscretFactory::Get().Discret (theShape,

View File

@@ -68,6 +68,20 @@ public:
Poly_Connect& thePolyConnect,
TColgp_Array1OfDir& theNormals);
//! Computes the absolute deflection value depending on the type of deflection in theDrawer:
//! <ul>
//! <li><b>Aspect_TOD_RELATIVE</b>: the absolute deflection is computed using the relative
//! deviation coefficient from theDrawer and the shape's bounding box;</li>
//! <li><b>Aspect_TOD_ABSOLUTE</b>: the maximal chordial deviation from theDrawer is returned.</li>
//! </ul>
//! In case of the type of deflection in theDrawer computed relative deflection for shape is stored as absolute deflection.
//! It is necessary to use it later on for sub-shapes.
//! This function should always be used to compute the deflection value for building
//! discrete representations of the shape (triangualtion, wireframe) to avoid incosistencies
//! between different representations of the shape and undesirable visual artifacts.
Standard_EXPORT static Standard_Real GetDeflection (const TopoDS_Shape& theShape,
const Handle(Prs3d_Drawer)& theDrawer);
//! Checks whether the shape is properly triangulated for a given display settings.
//! @param theShape [in] the shape.
//! @param theDrawer [in] the display settings.

View File

@@ -21,13 +21,12 @@
#include <BRepAdaptor_HSurface.hxx>
#include <OSD_Parallel.hxx>
#include <StdPrs_DeflectionCurve.hxx>
#include <StdPrs_ToolTriangulatedShape.hxx>
#include <StdPrs_Isolines.hxx>
#include <StdPrs_ShapeTool.hxx>
#include <StdPrs_ToolTriangulatedShape.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Prs3d_ShapeTool.hxx>
#include <Prs3d_IsoAspect.hxx>
#include <Prs3d.hxx>
#include <Poly_Connect.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Poly_Polygon3D.hxx>
#include <Poly_Triangulation.hxx>
@@ -115,7 +114,7 @@ void StdPrs_WFShape::Add (const Handle(Prs3d_Presentation)& thePresentation,
Prs3d_NListOfSequenceOfPnt aCommonPolylines;
const Handle(Prs3d_LineAspect)& aWireAspect = theDrawer->WireAspect();
const Standard_Real aShapeDeflection = Prs3d::GetDeflection (theShape, theDrawer);
const Standard_Real aShapeDeflection = StdPrs_ToolTriangulatedShape::GetDeflection (theShape, theDrawer);
// Draw isolines
{
@@ -154,7 +153,7 @@ void StdPrs_WFShape::Add (const Handle(Prs3d_Presentation)& thePresentation,
for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next())
{
const TopoDS_Face& aFace = TopoDS::Face (aFaceExplorer.Current());
if (theDrawer->IsoOnPlane() || !Prs3d_ShapeTool::IsPlanarFace (aFace))
if (theDrawer->IsoOnPlane() || !StdPrs_ShapeTool::IsPlanarFace (aFace))
{
aFaces[aNbFaces++] = aFace;
}
@@ -170,7 +169,7 @@ void StdPrs_WFShape::Add (const Handle(Prs3d_Presentation)& thePresentation,
for (TopExp_Explorer aFaceExplorer (theShape, TopAbs_FACE); aFaceExplorer.More(); aFaceExplorer.Next())
{
const TopoDS_Face& aFace = TopoDS::Face (aFaceExplorer.Current());
if (theDrawer->IsoOnPlane() || !Prs3d_ShapeTool::IsPlanarFace (aFace))
if (theDrawer->IsoOnPlane() || !StdPrs_ShapeTool::IsPlanarFace (aFace))
{
StdPrs_Isolines::Add (aFace, theDrawer, aShapeDeflection, *aUPolylinesPtr, *aVPolylinesPtr);
}
@@ -230,7 +229,7 @@ void StdPrs_WFShape::Add (const Handle(Prs3d_Presentation)& thePresentation,
Handle(Graphic3d_ArrayOfPrimitives) StdPrs_WFShape::AddAllEdges (const TopoDS_Shape& theShape,
const Handle(Prs3d_Drawer)& theDrawer)
{
const Standard_Real aShapeDeflection = Prs3d::GetDeflection (theShape, theDrawer);
const Standard_Real aShapeDeflection = StdPrs_ToolTriangulatedShape::GetDeflection (theShape, theDrawer);
Prs3d_NListOfSequenceOfPnt aPolylines;
addEdges (theShape, theDrawer, aShapeDeflection,
&aPolylines, &aPolylines, &aPolylines);
@@ -434,69 +433,9 @@ void StdPrs_WFShape::AddEdgesOnTriangulation (TColgp_SequenceOfPnt& theSegments,
continue;
}
}
const Handle(Poly_Triangulation)& T = BRep_Tool::Triangulation (aFace, aLocation);
if (T.IsNull())
if (const Handle(Poly_Triangulation)& aPolyTri = BRep_Tool::Triangulation (aFace, aLocation))
{
continue;
}
const TColgp_Array1OfPnt& aNodes = T->Nodes();
// Build the connect tool.
Poly_Connect aPolyConnect (T);
Standard_Integer aNbTriangles = T->NbTriangles();
Standard_Integer aT[3];
Standard_Integer aN[3];
// Count the free edges.
Standard_Integer aNbFree = 0;
for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI)
{
aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
for (Standard_Integer aJ = 0; aJ < 3; ++aJ)
{
if (aT[aJ] == 0)
{
++aNbFree;
}
}
}
if (aNbFree == 0)
{
continue;
}
// Allocate the arrays.
TColStd_Array1OfInteger aFree (1, 2 * aNbFree);
Standard_Integer aFreeIndex = 1;
const Poly_Array1OfTriangle& aTriangles = T->Triangles();
for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI)
{
aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
aTriangles (anI).Get (aN[0], aN[1], aN[2]);
for (Standard_Integer aJ = 0; aJ < 3; aJ++)
{
Standard_Integer k = (aJ + 1) % 3;
if (aT[aJ] == 0)
{
aFree (aFreeIndex) = aN[aJ];
aFree (aFreeIndex + 1) = aN[k];
aFreeIndex += 2;
}
}
}
// free edges
Standard_Integer aFreeHalfNb = aFree.Length() / 2;
for (Standard_Integer anI = 1; anI <= aFreeHalfNb; ++anI)
{
gp_Pnt aPoint1 = aNodes (aFree (2 * anI - 1)).Transformed (aLocation);
gp_Pnt aPoint2 = aNodes (aFree (2 * anI )).Transformed (aLocation);
theSegments.Append (aPoint1);
theSegments.Append (aPoint2);
Prs3d::AddFreeEdges (theSegments, aPolyTri, aLocation);
}
}
}