mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-19 13:40:49 +03:00
Compare commits
53 Commits
V7_7_1
...
CR0_720_Fi
Author | SHA1 | Date | |
---|---|---|---|
|
2ab2295cec | ||
|
84dd587638 | ||
|
28c0c6b155 | ||
|
47b0f294be | ||
|
7d6be4672b | ||
|
b453701e1f | ||
|
c23d6ec61f | ||
|
b05ff75a60 | ||
|
e49dc1e054 | ||
|
abca9f3eb8 | ||
|
68556f75f9 | ||
|
3d607bc062 | ||
|
365585ddfb | ||
|
c89ab82e4c | ||
|
cc964ef4d3 | ||
|
cb127824b2 | ||
|
fbebf6078c | ||
|
762fa70875 | ||
|
4dd6fb9a80 | ||
|
70608ec03d | ||
|
0842e31d95 | ||
|
51204152b9 | ||
|
d517575214 | ||
|
99d9eb3933 | ||
|
a3430df1d4 | ||
|
9f9ac0fb5a | ||
|
e0fd0b8797 | ||
|
09aae06737 | ||
|
eea07c2f60 | ||
|
9cee51b43b | ||
|
760a94d050 | ||
|
a8375ceaf0 | ||
|
55374b512e | ||
|
52a5d7a61d | ||
|
77676f1b6d | ||
|
515991ffef | ||
|
3d5d9d2b5e | ||
|
51e75dba6c | ||
|
b008680dc0 | ||
|
2b5ced28c3 | ||
|
1c4b27600f | ||
|
214171ff60 | ||
|
22f9125e1e | ||
|
1a196a871d | ||
|
5eba99e74b | ||
|
1560ac5528 | ||
|
4b46072ae9 | ||
|
eed77ff55c | ||
|
118e720920 | ||
|
80f77ed256 | ||
|
8f87d4a954 | ||
|
eeccb2515d | ||
|
b1ee6d0e4b |
@@ -79,7 +79,7 @@ if (WIN32)
|
||||
set (CSF_OpenGlLibs "opengl32.lib")
|
||||
endif()
|
||||
|
||||
else()
|
||||
else()
|
||||
|
||||
if (APPLE)
|
||||
set (CSF_objc "objc")
|
||||
@@ -112,5 +112,6 @@ if (WIN32)
|
||||
set (CSF_OpenGlLibs "GL")
|
||||
set (CSF_XwLibs "X11 Xext Xmu Xi")
|
||||
set (CSF_dl "dl")
|
||||
set (CSF_fontconfig "fontconfig")
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -1375,6 +1375,7 @@ proc osutils:csfList { theOS theCsfLibsMap theCsfFrmsMap } {
|
||||
set aLibsMap(CSF_TclTkLibs) ""
|
||||
set aLibsMap(CSF_QT) "QtCore QtGui"
|
||||
} else {
|
||||
set aLibsMap(CSF_fontconfig) "fontconfig"
|
||||
if { "$theOS" == "qnx" } {
|
||||
# CSF_ThreadLibs - pthread API is part of libc on QNX
|
||||
set aLibsMap(CSF_OpenGlLibs) "EGL GLESv2"
|
||||
|
@@ -1437,3 +1437,10 @@ The Error/Warning reporting system of the algorithms in Boolean Component (in al
|
||||
The methods returning the status of errors and warnings of the algorithms (ErrorStatus() and WarningStatus()) have been removed.
|
||||
Instead use methods HasErrors() and HasWarnings() to check for presence of errors and warnings, respectively.
|
||||
The full list of errors and warnings, with associated data such as problematic sub-shapes, can be obtained by method GetReport().
|
||||
|
||||
@section upgrade_occt730 Upgrade to OCCT 7.3.0
|
||||
|
||||
@subsection upgrade_730_BRepAdaptor_CompCurve Changes in BRepAdaptor_CompCurve
|
||||
|
||||
The method BRepAdaptor_CompCurve::SetPeriodic has been eliminated.
|
||||
Since new version, the method BRepAdaptor_CompCurve::IsPeriodic() will always return FALSE. Earlier, it could return TRUE in case if the wire contained only one edge based on periodic curve.
|
||||
|
@@ -9,6 +9,8 @@ pload VISUALIZATION
|
||||
|
||||
vinit View1 w=1024 h=1024
|
||||
vclear
|
||||
vdefaults -autoTriang 0
|
||||
vrenderparams -stats basic
|
||||
|
||||
# parameter NB defines number of spheres by each coordinate
|
||||
set NB 10
|
||||
@@ -23,11 +25,12 @@ for {set i 0} {$i < $NB} {incr i} {
|
||||
}
|
||||
}
|
||||
}
|
||||
eval compound $slist c
|
||||
incmesh c 0.006
|
||||
|
||||
puts "Measuring FPS of display of spheres as separate objects..."
|
||||
vaxo
|
||||
vsetdispmode 1
|
||||
eval vdisplay $slist
|
||||
eval vdisplay -dispMode 1 $slist
|
||||
vfit
|
||||
|
||||
# measure FPS
|
||||
@@ -35,16 +38,14 @@ puts [set fps_separate [vfps]]
|
||||
vclear
|
||||
|
||||
puts "Measuring FPS of display of spheres as single object..."
|
||||
eval compound $slist c
|
||||
vdisplay c
|
||||
vdisplay -dispMode 1 c
|
||||
|
||||
# measure FPS
|
||||
puts [set fps_compound [vfps]]
|
||||
vclear
|
||||
|
||||
# redisplay individual spheres, trying to avoid unnecessary internal updates
|
||||
#vfrustumculling 0 ;# try to disable updates of frustum culling structures
|
||||
eval vdisplay -mutable $slist
|
||||
eval vdisplay -dispMode 1 $slist
|
||||
|
||||
# auxiliary procedure to make random update of variable
|
||||
proc upd {theValueName theDeltaName theTime theToRand} {
|
||||
@@ -69,8 +70,10 @@ proc animateSpheres {{theDuration 10.0}} {
|
||||
for {set i 0} {$i < $::NB} {incr i $nb} {
|
||||
for {set j 0} {$j < $::NB} {incr j $nb} {
|
||||
for {set k 0} {$k < $::NB} {incr k $nb} {
|
||||
# mark animated spheres mutable for faster updates
|
||||
uplevel #0 vdisplay -dispMode 1 -mutable s$i$j$k
|
||||
# vaspects -noupdate s$i$j$k -setcolor red -setmaterial plastic
|
||||
vaspects -noupdate s$i$j$k -setcolor red
|
||||
uplevel #0 vaspects -noupdate s$i$j$k -setcolor red
|
||||
set x$i$j$k 0.0
|
||||
set y$i$j$k 0.0
|
||||
set z$i$j$k 0.0
|
||||
|
@@ -783,6 +783,7 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
BRepAdaptor_Surface surf1( aFace );
|
||||
Handle( Adaptor3d_HSurface ) surf2;
|
||||
Standard_Boolean isOffset = Standard_False;
|
||||
Offset = 0.0;
|
||||
|
||||
if (surf1.GetType() == GeomAbs_OffsetSurface)
|
||||
{
|
||||
@@ -801,7 +802,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
{
|
||||
aPlane = surf2->Plane();
|
||||
aSurfType = AIS_KOS_Plane;
|
||||
Offset = 0.;
|
||||
Result = Standard_True;
|
||||
}
|
||||
|
||||
@@ -817,7 +817,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
gp_Pln thePlane( LinePos, LineDir ^ ExtrusionDir);
|
||||
aPlane = thePlane;
|
||||
aSurfType = AIS_KOS_Plane;
|
||||
Offset = 0.;
|
||||
Result = Standard_True;
|
||||
}
|
||||
}
|
||||
@@ -826,7 +825,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
{
|
||||
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
||||
aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln();
|
||||
Offset = 0.0e0;
|
||||
}
|
||||
if (Result == Standard_False)
|
||||
{
|
||||
@@ -839,7 +837,6 @@ Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
|
||||
TheType == STANDARD_TYPE(Geom_ToroidalSurface))
|
||||
{
|
||||
aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
|
||||
Offset = 0.0e0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -899,20 +896,18 @@ gp_Pnt AIS::ProjectPointOnLine( const gp_Pnt & aPoint, const gp_Lin & aLine )
|
||||
//function : InitFaceLength
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void AIS::InitFaceLength (const TopoDS_Face& aFace,
|
||||
gp_Pln & aPlane,
|
||||
Handle(Geom_Surface) & aSurface,
|
||||
AIS_KindOfSurface & aSurfaceType,
|
||||
Standard_Real & anOffset)
|
||||
void AIS::InitFaceLength (const TopoDS_Face& theFace,
|
||||
gp_Pln& thePlane,
|
||||
Handle(Geom_Surface)& theSurface,
|
||||
AIS_KindOfSurface& theSurfaceType,
|
||||
Standard_Real& theOffset)
|
||||
{
|
||||
AIS::GetPlaneFromFace( aFace, aPlane, aSurface, aSurfaceType, anOffset );
|
||||
|
||||
if (Abs( anOffset ) > Precision::Confusion())
|
||||
if (AIS::GetPlaneFromFace (theFace, thePlane, theSurface, theSurfaceType, theOffset)
|
||||
&& Abs (theOffset) > Precision::Confusion())
|
||||
{
|
||||
aSurface = new Geom_OffsetSurface( aSurface, anOffset );
|
||||
anOffset = 0.0e0;
|
||||
theSurface = new Geom_OffsetSurface (theSurface, theOffset);
|
||||
theOffset = 0.0e0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -335,10 +335,9 @@ TCollection_ExtendedString AIS_Dimension::GetValueString (Standard_Real& theWidt
|
||||
if (myDrawer->DimensionAspect()->IsText3d())
|
||||
{
|
||||
// text width produced by BRepFont
|
||||
Font_BRepFont aFont (aTextAspect->Aspect()->Font().ToCString(),
|
||||
aTextAspect->Aspect()->GetTextFontAspect(),
|
||||
aTextAspect->Height());
|
||||
|
||||
Font_BRepFont aFont;
|
||||
if (aFont.FindAndInit (aTextAspect->Aspect()->Font(), aTextAspect->Aspect()->GetTextFontAspect(), aTextAspect->Height(), Font_StrictLevel_Any))
|
||||
{
|
||||
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
|
||||
{
|
||||
Standard_Utf32Char aCurrChar = *anIter;
|
||||
@@ -346,15 +345,15 @@ TCollection_ExtendedString AIS_Dimension::GetValueString (Standard_Real& theWidt
|
||||
theWidth += aFont.AdvanceX (aCurrChar, aNextChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Text width for 1:1 scale 2D case
|
||||
Handle(Font_FTFont) aFont = new Font_FTFont();
|
||||
aFont->Init (aTextAspect->Aspect()->Font().ToCString(),
|
||||
aTextAspect->Aspect()->GetTextFontAspect(),
|
||||
(const unsigned int)aTextAspect->Height(),
|
||||
THE_2D_TEXT_RESOLUTION);
|
||||
|
||||
Font_FTFontParams aFontParams;
|
||||
aFontParams.PointSize = (unsigned int )aTextAspect->Height();
|
||||
aFontParams.Resolution = THE_2D_TEXT_RESOLUTION;
|
||||
if (Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (aTextAspect->Aspect()->Font(), aTextAspect->Aspect()->GetTextFontAspect(), aFontParams, Font_StrictLevel_Any))
|
||||
{
|
||||
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
|
||||
{
|
||||
Standard_Utf32Char aCurrChar = *anIter;
|
||||
@@ -362,6 +361,7 @@ TCollection_ExtendedString AIS_Dimension::GetValueString (Standard_Real& theWidt
|
||||
theWidth += (Standard_Real) aFont->AdvanceX (aCurrChar, aNextChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aValueStr;
|
||||
}
|
||||
|
@@ -1386,15 +1386,8 @@ protected: //! @name internal methods
|
||||
if (myLastinMain.IsNull())
|
||||
return;
|
||||
|
||||
if (myLastinMain->IsAutoHilight())
|
||||
{
|
||||
myMainPM->ClearImmediateDraw();
|
||||
}
|
||||
else
|
||||
{
|
||||
myLastinMain->Selectable()->ClearDynamicHighlight (myMainPM);
|
||||
}
|
||||
}
|
||||
|
||||
protected: //! @name internal fields
|
||||
|
||||
|
@@ -1005,7 +1005,8 @@ void AIS_Manipulator::Disk::Init (const Standard_ShortReal theInnerRadius,
|
||||
gp_Ax3 aSystem (myPosition.Location(), myPosition.Direction());
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTransformation (aSystem, gp_Ax3());
|
||||
aTool.FillArray (myArray, myTriangulation, aTrsf);
|
||||
myArray = aTool.CreateTriangulation (aTrsf);
|
||||
myTriangulation = aTool.CreatePolyTriangulation (aTrsf);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1024,7 +1025,8 @@ void AIS_Manipulator::Sphere::Init (const Standard_ShortReal theRadius,
|
||||
Prs3d_ToolSphere aTool (theRadius, theSlicesNb, theStacksNb);
|
||||
gp_Trsf aTrsf;
|
||||
aTrsf.SetTranslation (gp_Vec(gp::Origin(), thePosition));
|
||||
aTool.FillArray (myArray, myTriangulation, aTrsf);
|
||||
myArray = aTool.CreateTriangulation (aTrsf);
|
||||
myTriangulation = aTool.CreatePolyTriangulation (aTrsf);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1060,24 +1062,24 @@ void AIS_Manipulator::Cube::Init (const gp_Ax1& thePosition, const Standard_Shor
|
||||
addTriangle (1, aBottomLeft, aV3, aV4, -thePosition.Direction());
|
||||
|
||||
// Front
|
||||
addTriangle (2, aV3, aV4, aV5, aFront);
|
||||
addTriangle (3, aV3, aV5, aTopRight, aFront);
|
||||
addTriangle (2, aV3, aV5, aV4, -aFront);
|
||||
addTriangle (3, aV3, aTopRight, aV5, -aFront);
|
||||
|
||||
// Back
|
||||
addTriangle (4, aBottomLeft, aV2, aV7, -aFront);
|
||||
addTriangle (5, aBottomLeft, aV7, aV6, -aFront);
|
||||
addTriangle (4, aBottomLeft, aV7, aV2, aFront);
|
||||
addTriangle (5, aBottomLeft, aV6, aV7, aFront);
|
||||
|
||||
// aTop
|
||||
addTriangle (6, aV7, aV6, aV5, thePosition.Direction());
|
||||
addTriangle (7, aTopRight, aV7, aV5, thePosition.Direction());
|
||||
|
||||
//Left
|
||||
addTriangle (8, aV6, aV5, aV4, -aRight);
|
||||
addTriangle (9, aBottomLeft, aV6, aV4, -aRight);
|
||||
// Left
|
||||
addTriangle (8, aV6, aV4, aV5, aRight);
|
||||
addTriangle (9, aBottomLeft, aV4, aV6, aRight);
|
||||
|
||||
// Right
|
||||
addTriangle (10, aV3, aTopRight, aV7, aRight);
|
||||
addTriangle (11, aV3, aV7, aV2, aRight);
|
||||
addTriangle (10, aV3, aV7, aTopRight, -aRight);
|
||||
addTriangle (11, aV3, aV2, aV7, -aRight);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1148,6 +1150,7 @@ void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& t
|
||||
anArrowLength,
|
||||
myFacettesNumber);
|
||||
myTranslatorGroup = Prs3d_Root::NewGroup (thePrs);
|
||||
myTranslatorGroup->SetClosed (true);
|
||||
myTranslatorGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
|
||||
myTranslatorGroup->AddPrimitiveArray (myTriangleArray);
|
||||
|
||||
@@ -1169,6 +1172,7 @@ void AIS_Manipulator::Axis::Compute (const Handle(PrsMgr_PresentationManager)& t
|
||||
myCube.Init (gp_Ax1 (myCubePos, myReferenceAxis.Direction()), myBoxSize);
|
||||
|
||||
myScalerGroup = Prs3d_Root::NewGroup (thePrs);
|
||||
myScalerGroup->SetClosed (true);
|
||||
myScalerGroup->SetGroupPrimitivesAspect (theAspect->Aspect());
|
||||
myScalerGroup->AddPrimitiveArray (myCube.Array());
|
||||
|
||||
|
@@ -261,14 +261,14 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr
|
||||
if (myHasFlipping)
|
||||
{
|
||||
// Get width and height of text
|
||||
Font_FTFont aFont;
|
||||
unsigned int aResolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
|
||||
if (aFont.Init (anAsp->Aspect()->Font().ToCString(),
|
||||
anAsp->Aspect()->GetTextFontAspect(), (unsigned int)anAsp->Height(), aResolution))
|
||||
Font_FTFontParams aFontParams;
|
||||
aFontParams.PointSize = (unsigned int )anAsp->Height();
|
||||
aFontParams.Resolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
|
||||
if (Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (anAsp->Aspect()->Font(), anAsp->Aspect()->GetTextFontAspect(), aFontParams))
|
||||
{
|
||||
isInit = Standard_True;
|
||||
const NCollection_String aText (myText.ToExtString());
|
||||
Font_Rect aBndBox = aFont.BoundingBox (aText, anAsp->HorizontalJustification(), anAsp->VerticalJustification());
|
||||
Font_Rect aBndBox = aFont->BoundingBox (aText, anAsp->HorizontalJustification(), anAsp->VerticalJustification());
|
||||
Standard_Real aWidth = Abs (aBndBox.Width());
|
||||
Standard_Real aHeight = Abs (aBndBox.Height());
|
||||
gp_Pnt aCenterOfLabel = aPosition;
|
||||
|
@@ -458,7 +458,7 @@ GeomAbs_CurveType Adaptor2d_OffsetCurve::GetType() const {
|
||||
return GeomAbs_Circle;
|
||||
|
||||
default:
|
||||
return GeomAbs_OtherCurve;
|
||||
return GeomAbs_OffsetCurve;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -650,3 +650,27 @@ Handle(Geom2d_BSplineCurve) Adaptor2d_OffsetCurve::BSpline() const
|
||||
"Adaptor2d_OffsetCurve::BSpline() - wrong curve type");
|
||||
return myCurve->BSpline();
|
||||
}
|
||||
|
||||
static Standard_Integer nbPoints(const Handle(Adaptor2d_HCurve2d)& theCurve)
|
||||
{
|
||||
|
||||
Standard_Integer nbs = 20;
|
||||
|
||||
if (theCurve->GetType() == GeomAbs_BezierCurve)
|
||||
{
|
||||
nbs = Max(nbs, 3 + theCurve->NbPoles());
|
||||
}
|
||||
else if (theCurve->GetType() == GeomAbs_BSplineCurve) {
|
||||
nbs = Max(nbs, theCurve->NbKnots() * theCurve->Degree());
|
||||
}
|
||||
|
||||
if (nbs > 300)
|
||||
nbs = 300;
|
||||
return nbs;
|
||||
|
||||
}
|
||||
|
||||
Standard_Integer Adaptor2d_OffsetCurve::NbSamples() const
|
||||
{
|
||||
return nbPoints(myCurve);
|
||||
}
|
||||
|
@@ -174,6 +174,8 @@ public:
|
||||
|
||||
Standard_EXPORT Handle(Geom2d_BSplineCurve) BSpline() const Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT Standard_Integer NbSamples() const Standard_OVERRIDE;;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -67,3 +67,6 @@ Warning: Removal of internal boundaries among Faces has failed
|
||||
|
||||
.BOPAlgo_AlertRemovalOfIBForEdgesFailed
|
||||
Warning: Removal of internal boundaries among Edges has failed
|
||||
|
||||
.BOPAlgo_AlertSolidBuilderUnusedFaces
|
||||
Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation
|
||||
|
@@ -78,4 +78,7 @@ DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertShellSplitterFailed)
|
||||
//! Some edges are too small and have no valid range
|
||||
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertTooSmallEdge)
|
||||
|
||||
//! Some of the faces passed to the Solid Builder algorithm have not been classified
|
||||
//! and not used for solids creation
|
||||
DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertSolidBuilderUnusedFaces)
|
||||
#endif // _BOPAlgo_Alerts_HeaderFile
|
||||
|
@@ -69,4 +69,7 @@ static const char BOPAlgo_BOPAlgo_msg[] =
|
||||
"Warning: Removal of internal boundaries among Faces has failed\n"
|
||||
"\n"
|
||||
".BOPAlgo_AlertRemovalOfIBForEdgesFailed\n"
|
||||
"Warning: Removal of internal boundaries among Edges has failed\n";
|
||||
"Warning: Removal of internal boundaries among Edges has failed\n"
|
||||
"\n"
|
||||
".BOPAlgo_AlertSolidBuilderUnusedFaces\n"
|
||||
"Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n";
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include <BOPAlgo_BuilderSolid.hxx>
|
||||
#include <BOPAlgo_ShellSplitter.hxx>
|
||||
#include <BOPAlgo_Alerts.hxx>
|
||||
#include <BOPAlgo_Tools.hxx>
|
||||
#include <BOPCol_BoxBndTree.hxx>
|
||||
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_DataMapOfShapeShape.hxx>
|
||||
@@ -127,127 +128,7 @@ typedef NCollection_DataMap
|
||||
//
|
||||
typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator
|
||||
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB;
|
||||
//
|
||||
//=======================================================================
|
||||
//function : BOPAlgo_FacePnt
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
class BOPAlgo_FacePnt {
|
||||
public:
|
||||
BOPAlgo_FacePnt() {
|
||||
}
|
||||
//
|
||||
virtual ~BOPAlgo_FacePnt() {
|
||||
}
|
||||
//
|
||||
void SetFace(const TopoDS_Face& aFace) {
|
||||
myFace=aFace;
|
||||
}
|
||||
//
|
||||
const TopoDS_Face& Face()const {
|
||||
return myFace;
|
||||
}
|
||||
//
|
||||
void SetPnt(const gp_Pnt& aPnt) {
|
||||
myPnt=aPnt;
|
||||
}
|
||||
//
|
||||
const gp_Pnt& Pnt()const {
|
||||
return myPnt;
|
||||
}
|
||||
//
|
||||
protected:
|
||||
gp_Pnt myPnt;
|
||||
TopoDS_Face myFace;
|
||||
};
|
||||
//
|
||||
typedef BOPCol_NCVector
|
||||
<BOPAlgo_FacePnt> BOPAlgo_VectorOfFacePnt;
|
||||
//
|
||||
//=======================================================================
|
||||
//function : BOPAlgo_FaceSolid
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
class BOPAlgo_FaceSolid : public BOPAlgo_Algo {
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
BOPAlgo_FaceSolid() :
|
||||
myIsInternalFace(Standard_False) {
|
||||
}
|
||||
//
|
||||
virtual ~BOPAlgo_FaceSolid() {
|
||||
}
|
||||
//
|
||||
void SetFace(const TopoDS_Face& aFace) {
|
||||
myFace=aFace;
|
||||
}
|
||||
//
|
||||
const TopoDS_Face& Face()const {
|
||||
return myFace;
|
||||
}
|
||||
//
|
||||
void SetSolid(const TopoDS_Solid& aSolid) {
|
||||
mySolid=aSolid;
|
||||
}
|
||||
//
|
||||
const TopoDS_Solid& Solid()const {
|
||||
return mySolid;
|
||||
}
|
||||
//
|
||||
void SetPnt(const gp_Pnt& aPnt) {
|
||||
myPnt=aPnt;
|
||||
}
|
||||
//
|
||||
const gp_Pnt& Pnt()const {
|
||||
return myPnt;
|
||||
}
|
||||
void SetContext(const Handle(IntTools_Context)& aContext) {
|
||||
myContext=aContext;
|
||||
}
|
||||
//
|
||||
const Handle(IntTools_Context)& Context()const {
|
||||
return myContext;
|
||||
}
|
||||
//
|
||||
Standard_Boolean IsInternalFace() const {
|
||||
return myIsInternalFace;
|
||||
}
|
||||
//
|
||||
virtual void Perform () {
|
||||
TopAbs_State aState;
|
||||
//
|
||||
BOPAlgo_Algo::UserBreak();
|
||||
//
|
||||
aState=BOPTools_AlgoTools::ComputeState(myPnt, mySolid,
|
||||
Precision::Confusion(),
|
||||
myContext);
|
||||
//
|
||||
myIsInternalFace=(aState==TopAbs_IN);
|
||||
}
|
||||
//
|
||||
protected:
|
||||
Standard_Boolean myIsInternalFace;
|
||||
gp_Pnt myPnt;
|
||||
TopoDS_Face myFace;
|
||||
TopoDS_Solid mySolid;
|
||||
Handle(IntTools_Context) myContext;
|
||||
};
|
||||
//=======================================================================
|
||||
typedef BOPCol_NCVector
|
||||
<BOPAlgo_FaceSolid> BOPAlgo_VectorOfFaceSolid;
|
||||
//
|
||||
typedef BOPCol_ContextFunctor
|
||||
<BOPAlgo_FaceSolid,
|
||||
BOPAlgo_VectorOfFaceSolid,
|
||||
Handle(IntTools_Context),
|
||||
IntTools_Context> BOPAlgo_FaceSolidFunctor;
|
||||
//
|
||||
typedef BOPCol_ContextCnt
|
||||
<BOPAlgo_FaceSolidFunctor,
|
||||
BOPAlgo_VectorOfFaceSolid,
|
||||
Handle(IntTools_Context)> BOPAlgo_FaceSolidCnt;
|
||||
//
|
||||
//=======================================================================
|
||||
|
||||
//=======================================================================
|
||||
@@ -766,49 +647,29 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
|
||||
return;
|
||||
}
|
||||
//
|
||||
Standard_Boolean bIsInternalFace;
|
||||
Standard_Integer k, aNbVFS, aNbSLF, aNbVFP, aNbA;
|
||||
BRep_Builder aBB;
|
||||
TopoDS_Iterator aIt;
|
||||
TopExp_Explorer aExp;
|
||||
BOPCol_ListIteratorOfListOfShape aItLS;
|
||||
BOPCol_IndexedMapOfShape aMFs;
|
||||
BOPCol_ListOfShape aLSI;
|
||||
BOPAlgo_VectorOfFaceSolid aVFS;
|
||||
BOPAlgo_VectorOfFacePnt aVFP;
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI;
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
BOPCol_BoxBndTree aBBTree;
|
||||
NCollection_UBTreeFiller
|
||||
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
|
||||
//
|
||||
aNbA=myAreas.Extent();
|
||||
Standard_Integer aNbA = myAreas.Extent();
|
||||
//
|
||||
// 1. aVFP
|
||||
// Fill Tree with boxes
|
||||
aItLS.Initialize(myLoopsInternal);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aShell=aItLS.Value();
|
||||
aIt.Initialize(aShell);
|
||||
TopoDS_Iterator aIt(aShell);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
|
||||
//
|
||||
if (!aMFs.Contains(aF)) {
|
||||
if (!aMFs.Contains(aF))
|
||||
{
|
||||
aMFs.Add(aF);
|
||||
//
|
||||
gp_Pnt aP;
|
||||
gp_Pnt2d aP2D;
|
||||
//
|
||||
if (aNbA) {
|
||||
BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext);
|
||||
}
|
||||
//
|
||||
BOPAlgo_FacePnt& aFP=aVFP.Append1();
|
||||
aFP.SetFace(aF);
|
||||
aFP.SetPnt(aP);
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
if (!aNbA) {
|
||||
// 7b. "Rest" faces treatment
|
||||
TopoDS_Solid aSolid;
|
||||
@@ -826,146 +687,81 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
|
||||
return; // =>
|
||||
}//if (!aNbA) {
|
||||
//
|
||||
// 2. Prepare TreeFiller
|
||||
aNbVFP=aVFP.Extent();
|
||||
for(k=0; k<aNbVFP; ++k) {
|
||||
Bnd_Box aBox;
|
||||
//
|
||||
const BOPAlgo_FacePnt& aFP=aVFP(k);
|
||||
const TopoDS_Face& aF=aFP.Face();
|
||||
//
|
||||
BRepBndLib::Add(aF, aBox);
|
||||
aTreeFiller.Add(k, aBox);
|
||||
}
|
||||
//
|
||||
aTreeFiller.Fill();
|
||||
//
|
||||
// 3. Face/Solid candidates: aVFS
|
||||
aItLS.Initialize(myAreas);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
Bnd_Box aBox;
|
||||
//
|
||||
TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value()));
|
||||
BRepBndLib::Add(aSolid, aBox);
|
||||
//
|
||||
aMFs.Clear();
|
||||
aExp.Init(aSolid, TopAbs_FACE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
const TopoDS_Shape& aFs=aExp.Current();
|
||||
aMFs.Add(aFs);
|
||||
}
|
||||
//
|
||||
aSelector.Clear();
|
||||
aSelector.SetBox(aBox);
|
||||
//
|
||||
aBBTree.Select(aSelector);
|
||||
//
|
||||
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
|
||||
aItLI.Initialize(aLI);
|
||||
for (; aItLI.More(); aItLI.Next()) {
|
||||
k=aItLI.Value();
|
||||
const BOPAlgo_FacePnt& aFP=aVFP(k);
|
||||
const TopoDS_Face& aF=aFP.Face();
|
||||
if (aMFs.Contains(aF)) {
|
||||
|
||||
// Prepare list of faces to classify
|
||||
TopTools_ListOfShape aLFaces;
|
||||
Standard_Integer i, aNbF = aMFs.Extent();
|
||||
for (i = 1; i <= aNbF; ++i)
|
||||
aLFaces.Append(aMFs(i));
|
||||
|
||||
// Map of solids with IN faces
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMSLF;
|
||||
|
||||
// Perform classification
|
||||
BOPAlgo_Tools::ClassifyFaces(aLFaces, myAreas, myRunParallel, myContext, aMSLF);
|
||||
|
||||
// Update Solids by internal Faces
|
||||
|
||||
BOPCol_MapOfShape aMFDone;
|
||||
|
||||
Standard_Integer aNbS = aMSLF.Extent();
|
||||
for (i = 1; i <= aNbS; ++i)
|
||||
{
|
||||
const TopoDS_Shape& aSolid = aMSLF.FindKey(i);
|
||||
TopoDS_Shape *pSolid = (TopoDS_Shape*)&aSolid;
|
||||
|
||||
const TopTools_ListOfShape& aLF = aMSLF(i);
|
||||
if (aLF.IsEmpty())
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const gp_Pnt& aP=aFP.Pnt();
|
||||
//
|
||||
BOPAlgo_FaceSolid& aFS=aVFS.Append1();
|
||||
aFS.SetPnt(aP);
|
||||
aFS.SetFace(aF);
|
||||
aFS.SetSolid(aSolid);
|
||||
}
|
||||
}
|
||||
//
|
||||
aNbVFS=aVFS.Extent();
|
||||
if (!aNbVFS) {
|
||||
return;
|
||||
}
|
||||
// 4. Refine candidates
|
||||
//=============================================================
|
||||
BOPAlgo_FaceSolidCnt::Perform(myRunParallel, aVFS, myContext);
|
||||
//=============================================================
|
||||
//
|
||||
// 5. Solid/Faces: aMSLF
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMSLF;
|
||||
BOPCol_MapOfShape aMFProcessed;
|
||||
//
|
||||
for (k=0; k < aNbVFS; ++k) {
|
||||
const BOPAlgo_FaceSolid& aFS=aVFS(k);
|
||||
//
|
||||
const TopoDS_Solid& aSolid=aFS.Solid();
|
||||
const TopoDS_Face& aF=aFS.Face();
|
||||
//
|
||||
bIsInternalFace=aFS.IsInternalFace();
|
||||
if (!bIsInternalFace) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (aMSLF.Contains(aSolid)) {
|
||||
BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid);
|
||||
aLF.Append(aF);
|
||||
}
|
||||
else {
|
||||
BOPCol_ListOfShape aLF;
|
||||
//
|
||||
aLF.Append(aF);
|
||||
aMSLF.Add(aSolid, aLF);
|
||||
}
|
||||
}// for (k=0; k < aNbVE; ++k) {
|
||||
//
|
||||
// 6. Update Solids by internal Faces
|
||||
aNbSLF=aMSLF.Extent();
|
||||
for (k=1; k <= aNbSLF; ++k) {
|
||||
const TopoDS_Shape& aSolid=aMSLF.FindKey(k);
|
||||
TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid;
|
||||
//
|
||||
const BOPCol_ListOfShape& aLF=aMSLF(k);
|
||||
//
|
||||
aMFs.Clear();
|
||||
|
||||
TopTools_IndexedMapOfShape aMF;
|
||||
aItLS.Initialize(aLF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aF=aItLS.Value();
|
||||
aMFs.Add(aF);
|
||||
aMFProcessed.Add(aF);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Shape& aF = aItLS.Value();
|
||||
aMF.Add(aF);
|
||||
aMFDone.Add(aF);
|
||||
}
|
||||
//
|
||||
aLSI.Clear();
|
||||
MakeInternalShells(aMFs, aLSI);
|
||||
MakeInternalShells(aMF, aLSI);
|
||||
//
|
||||
aItLS.Initialize(aLSI);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aSI=aItLS.Value();
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Shape& aSI = aItLS.Value();
|
||||
aBB.Add (*pSolid, aSI);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 7. "Rest" faces treatment (if there are)
|
||||
aMFs.Clear();
|
||||
for (k=0; k < aNbVFS; ++k) {
|
||||
const BOPAlgo_FaceSolid& aFS=aVFS(k);
|
||||
//
|
||||
const TopoDS_Face& aF=aFS.Face();
|
||||
if (!aMFProcessed.Contains(aF)) {
|
||||
aMFs.Add(aF);
|
||||
|
||||
// Find all unclassified faces and warn the user about them.
|
||||
TopTools_IndexedMapOfShape aMFUnUsed;
|
||||
|
||||
for (i = 1; i <= aNbF; ++i)
|
||||
{
|
||||
const TopoDS_Shape& aF = aMFs(i);
|
||||
if (!aMFDone.Contains(aF))
|
||||
aMFUnUsed.Add(aF);
|
||||
}
|
||||
}
|
||||
//
|
||||
aNbFI=aMFs.Extent();
|
||||
if (aNbFI) {
|
||||
TopoDS_Solid aSolid;
|
||||
aBB.MakeSolid(aSolid);
|
||||
//
|
||||
|
||||
if (aMFUnUsed.Extent())
|
||||
{
|
||||
aLSI.Clear();
|
||||
MakeInternalShells(aMFs, aLSI);
|
||||
//
|
||||
aItLS.Initialize(aLSI);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
|
||||
//TopoDS_Solid aShape;
|
||||
//aBB.MakeSolid (aShape);
|
||||
TopoDS_Compound aShape;
|
||||
aBB.MakeCompound (aShape);
|
||||
|
||||
aItLS.Initialize (aLSI);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Shape& aSI=aItLS.Value();
|
||||
aBB.Add (aSolid, aSI);
|
||||
aBB.Add (aShape, aSI);
|
||||
}
|
||||
myAreas.Append(aSolid);
|
||||
//myAreas.Append (aShape);
|
||||
AddWarning (new BOPAlgo_AlertSolidBuilderUnusedFaces (aShape));
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
|
@@ -19,6 +19,7 @@
|
||||
//
|
||||
#include <Precision.hxx>
|
||||
//
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_UBTreeFiller.hxx>
|
||||
//
|
||||
#include <Bnd_Box.hxx>
|
||||
@@ -43,9 +44,13 @@
|
||||
#include <BRepClass3d_SolidClassifier.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
//
|
||||
#include <BOPAlgo_Tools.hxx>
|
||||
//
|
||||
#include <BOPCol_IndexedMapOfShape.hxx>
|
||||
#include <BOPCol_MapOfShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeBox.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeShape.hxx>
|
||||
#include <BOPCol_ListOfShape.hxx>
|
||||
#include <BOPCol_BoxBndTree.hxx>
|
||||
#include <BOPCol_ListOfInteger.hxx>
|
||||
@@ -131,367 +136,6 @@ class BOPAlgo_ShapeBox {
|
||||
typedef BOPCol_NCVector<BOPAlgo_ShapeBox> BOPAlgo_VectorOfShapeBox;
|
||||
//
|
||||
//=======================================================================
|
||||
// class: BOPAlgo_FillIn3DParts
|
||||
//
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_FillIn3DParts
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo {
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
BOPAlgo_FillIn3DParts(){
|
||||
myHasImage=Standard_False;
|
||||
myBBTree=NULL;
|
||||
myVSB=NULL;
|
||||
};
|
||||
//
|
||||
virtual ~BOPAlgo_FillIn3DParts(){
|
||||
};
|
||||
//
|
||||
void SetSolid(const TopoDS_Solid& aS) {
|
||||
mySolid=aS;
|
||||
};
|
||||
//
|
||||
const TopoDS_Solid& Solid()const {
|
||||
return mySolid;
|
||||
};
|
||||
//
|
||||
void SetDraftSolid(const TopoDS_Solid& aS) {
|
||||
myDraftSolid=aS;
|
||||
};
|
||||
//
|
||||
const TopoDS_Solid& DraftSolid()const {
|
||||
return myDraftSolid;
|
||||
};
|
||||
//
|
||||
void SetHasImage(const Standard_Boolean bFlag) {
|
||||
myHasImage=bFlag;
|
||||
};
|
||||
//
|
||||
Standard_Boolean HasImage()const {
|
||||
return myHasImage;
|
||||
};
|
||||
//
|
||||
void SetBoxS(const Bnd_Box& aBox) {
|
||||
myBoxS=aBox;
|
||||
};
|
||||
//
|
||||
const Bnd_Box& BoxS()const {
|
||||
return myBoxS;
|
||||
};
|
||||
//
|
||||
void SetLIF(const BOPCol_ListOfShape& aLIF) {
|
||||
myLIF=aLIF;
|
||||
};
|
||||
//
|
||||
const BOPCol_ListOfShape& LIF()const {
|
||||
return myLIF;
|
||||
};
|
||||
//
|
||||
void SetBBTree(const BOPCol_BoxBndTree& aBBTree) {
|
||||
myBBTree=(BOPCol_BoxBndTree*)&aBBTree;
|
||||
};
|
||||
//
|
||||
void SetVSB(const BOPAlgo_VectorOfShapeBox& aVSB) {
|
||||
myVSB=(BOPAlgo_VectorOfShapeBox*)&aVSB;
|
||||
};
|
||||
//
|
||||
//
|
||||
void SetContext(const Handle(IntTools_Context)& aContext) {
|
||||
myContext=aContext;
|
||||
}
|
||||
//
|
||||
const Handle(IntTools_Context)& Context()const {
|
||||
return myContext;
|
||||
}
|
||||
//
|
||||
virtual void Perform();
|
||||
//
|
||||
|
||||
//
|
||||
const BOPCol_ListOfShape& LFIN()const {
|
||||
return myLFIN;
|
||||
};
|
||||
|
||||
protected:
|
||||
void MapEdgesAndFaces
|
||||
(const TopoDS_Shape& ,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& ,
|
||||
const Handle(NCollection_BaseAllocator)& );
|
||||
|
||||
void MakeConnexityBlock
|
||||
(const BOPCol_ListOfShape& ,
|
||||
const BOPCol_IndexedMapOfShape& ,
|
||||
const BOPCol_MapOfShape& ,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& ,
|
||||
BOPCol_ListOfShape& ,
|
||||
const Handle(NCollection_BaseAllocator)& );
|
||||
//
|
||||
protected:
|
||||
TopoDS_Solid mySolid;
|
||||
TopoDS_Solid myDraftSolid;
|
||||
Standard_Boolean myHasImage;
|
||||
Bnd_Box myBoxS;
|
||||
BOPCol_ListOfShape myLIF;
|
||||
BOPCol_ListOfShape myLFIN;
|
||||
//
|
||||
BOPCol_BoxBndTree* myBBTree;
|
||||
BOPAlgo_VectorOfShapeBox* myVSB;
|
||||
//
|
||||
TopoDS_Iterator myItF;
|
||||
TopoDS_Iterator myItW;
|
||||
|
||||
Handle(IntTools_Context) myContext;
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : BOPAlgo_FillIn3DParts::Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::Perform()
|
||||
{
|
||||
Handle(NCollection_BaseAllocator) aAlr1;
|
||||
BOPAlgo_Algo::UserBreak();
|
||||
//
|
||||
Standard_Integer aNbFP, k, nFP, iIsIN;
|
||||
Standard_Real aTolPC;
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
|
||||
BOPCol_ListIteratorOfListOfShape aItLS;
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
//
|
||||
aAlr1=
|
||||
NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
//
|
||||
BOPCol_ListOfShape aLFP(aAlr1);
|
||||
BOPCol_ListOfShape aLCBF(aAlr1);
|
||||
BOPCol_MapOfShape aMFDone(100, aAlr1);
|
||||
BOPCol_IndexedMapOfShape aME(100, aAlr1);
|
||||
BOPCol_IndexedMapOfShape aMF(100, aAlr1);
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(100, aAlr1);
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, aAlr1);
|
||||
//
|
||||
aTolPC=Precision::Confusion();
|
||||
myLFIN.Clear();
|
||||
BOPAlgo_VectorOfShapeBox& aVSB=*myVSB;
|
||||
//
|
||||
// 1. aMEF - EF map for myDraftSolid
|
||||
BOPTools::MapShapesAndAncestors(myDraftSolid,
|
||||
TopAbs_EDGE,
|
||||
TopAbs_FACE,
|
||||
aMEF);
|
||||
|
||||
//
|
||||
// 2. Faces from myDraftSolid and its own internal faces => aMF
|
||||
BOPTools::MapShapes(myDraftSolid, TopAbs_FACE, aMF);
|
||||
aItLS.Initialize(myLIF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFI=aItLS.Value();
|
||||
aMF.Add(aFI);
|
||||
}
|
||||
// aME - Edges from DraftSolid [i.e. edges to stop]
|
||||
BOPTools::MapShapes(myDraftSolid, TopAbs_EDGE, aME);
|
||||
//
|
||||
// 3. Select boxes of faces that are not out of aBoxS
|
||||
aSelector.Clear();
|
||||
aSelector.SetBox(myBoxS);
|
||||
//
|
||||
aNbFP=myBBTree->Select(aSelector);
|
||||
const BOPCol_ListOfInteger& aLIFPx=aSelector.Indices();
|
||||
//
|
||||
// 4. aIVec, aLIFP - faces to process
|
||||
BOPCol_ListOfInteger aLIFP(aAlr1);
|
||||
BOPCol_NCVector<Standard_Integer> aIVec(256, aAlr1);
|
||||
//
|
||||
k=0;
|
||||
aItLI.Initialize(aLIFPx);
|
||||
for (; aItLI.More(); aItLI.Next()) {
|
||||
nFP=aItLI.Value();
|
||||
const TopoDS_Shape& aFP=aVSB(nFP).Shape();
|
||||
if (!aMF.Contains(aFP)) {
|
||||
MapEdgesAndFaces(aFP, aMEFP, aAlr1);
|
||||
aLIFP.Append(nFP);
|
||||
aIVec.Append1()=nFP;
|
||||
++k;
|
||||
}
|
||||
}
|
||||
aNbFP=k;
|
||||
//
|
||||
// sort indices
|
||||
std::sort(aIVec.begin(), aIVec.end());
|
||||
//
|
||||
// 5. Collect faces that are IN mySolid [ myLFIN ]
|
||||
for (k=0; k<aNbFP; ++k) {
|
||||
nFP = aIVec(k);
|
||||
const BOPAlgo_ShapeBox& aSBF=aVSB(nFP);
|
||||
const TopoDS_Face& aFP=(*(TopoDS_Face*)&aSBF.Shape());
|
||||
//
|
||||
if (!aMFDone.Add(aFP)) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
iIsIN=BOPTools_AlgoTools::IsInternalFace
|
||||
(aFP, myDraftSolid, aMEF, aTolPC, myContext);
|
||||
//
|
||||
aLFP.Clear();
|
||||
aLFP.Append(aFP);
|
||||
//
|
||||
aItLI1.Initialize(aLIFP);
|
||||
for (; aItLI1.More(); aItLI1.Next()) {
|
||||
const TopoDS_Shape& aFx=aVSB(aItLI1.Value()).Shape();
|
||||
if (!aMFDone.Contains(aFx)) {
|
||||
aLFP.Append(aFx);
|
||||
}
|
||||
}
|
||||
//
|
||||
aLCBF.Clear();
|
||||
//
|
||||
MakeConnexityBlock(aLFP, aME, aMFDone, aMEFP, aLCBF, aAlr1);
|
||||
//
|
||||
aItLS.Initialize(aLCBF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFx=aItLS.Value();
|
||||
aMFDone.Add(aFx);
|
||||
if (iIsIN) {
|
||||
myLFIN.Append(aFx);
|
||||
}
|
||||
}
|
||||
} // for (k=0; k<aNbFP; ++k) {
|
||||
}
|
||||
//=======================================================================
|
||||
// function: MapEdgesAndFaces
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::MapEdgesAndFaces
|
||||
(const TopoDS_Shape& aF,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
{
|
||||
myItF.Initialize(aF);
|
||||
for (; myItF.More(); myItF.Next()) {
|
||||
const TopoDS_Shape& aW=myItF.Value();
|
||||
if (aW.ShapeType()!=TopAbs_WIRE) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
myItW.Initialize(aW);
|
||||
for (; myItW.More(); myItW.Next()) {
|
||||
const TopoDS_Shape& aE=myItW.Value();
|
||||
//
|
||||
if (aMEF.Contains(aE)) {
|
||||
BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
|
||||
aLF.Append(aF);
|
||||
}
|
||||
else {
|
||||
BOPCol_ListOfShape aLS(theAllocator);
|
||||
//
|
||||
aLS.Append(aF);
|
||||
aMEF.Add(aE, aLS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
// function: MakeConnexityBlock
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::MakeConnexityBlock
|
||||
(const BOPCol_ListOfShape& theLFIn,
|
||||
const BOPCol_IndexedMapOfShape& theMEAvoid,
|
||||
const BOPCol_MapOfShape& aMFDone,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
|
||||
BOPCol_ListOfShape& theLCB,
|
||||
const Handle(NCollection_BaseAllocator)& theAlr)
|
||||
{
|
||||
Standard_Integer aNbF, aNbAdd1, aNbAdd, i;
|
||||
BOPCol_ListIteratorOfListOfShape aIt;
|
||||
//
|
||||
BOPCol_IndexedMapOfShape aMCB(100, theAlr);
|
||||
BOPCol_IndexedMapOfShape aMAdd(100, theAlr);
|
||||
BOPCol_IndexedMapOfShape aMAdd1(100, theAlr);
|
||||
//
|
||||
aNbF=theLFIn.Extent();
|
||||
//
|
||||
// 2. aMCB
|
||||
const TopoDS_Shape& aF1=theLFIn.First();
|
||||
aMAdd.Add(aF1);
|
||||
//
|
||||
for(;;) {
|
||||
aMAdd1.Clear();
|
||||
aNbAdd = aMAdd.Extent();
|
||||
for (i=1; i<=aNbAdd; ++i) {
|
||||
const TopoDS_Shape& aF=aMAdd(i);
|
||||
//
|
||||
myItF.Initialize(aF);
|
||||
for (; myItF.More(); myItF.Next()) {
|
||||
const TopoDS_Shape& aW=myItF.Value();
|
||||
if (aW.ShapeType()!=TopAbs_WIRE) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
myItW.Initialize(aW);
|
||||
for (; myItW.More(); myItW.Next()) {
|
||||
const TopoDS_Shape& aE=myItW.Value();
|
||||
if (theMEAvoid.Contains(aE)){
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
|
||||
aIt.Initialize(aLF);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aFx=aIt.Value();
|
||||
if (aFx.IsSame(aF)) {
|
||||
continue;
|
||||
}
|
||||
if (aMCB.Contains(aFx)) {
|
||||
continue;
|
||||
}
|
||||
if (aMFDone.Contains(aFx)) {
|
||||
continue;
|
||||
}
|
||||
aMAdd1.Add(aFx);
|
||||
}
|
||||
}// for (; myItW.More(); myItW.Next()) {
|
||||
}// for (; myItF.More(); myItF.Next()) {
|
||||
aMCB.Add(aF);
|
||||
}// for (i=1; i<=aNbAdd; ++i) {
|
||||
//
|
||||
aNbAdd1=aMAdd1.Extent();
|
||||
if (!aNbAdd1) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
aMAdd.Clear();
|
||||
for (i=1; i<=aNbAdd1; ++i) {
|
||||
const TopoDS_Shape& aFAdd=aMAdd1(i);
|
||||
aMAdd.Add(aFAdd);
|
||||
}
|
||||
//
|
||||
}//while(1) {
|
||||
//
|
||||
aNbF=aMCB.Extent();
|
||||
for (i=1; i<=aNbF; ++i) {
|
||||
const TopoDS_Shape& aF=aMCB(i);
|
||||
theLCB.Append(aF);
|
||||
}
|
||||
}
|
||||
//
|
||||
typedef BOPCol_NCVector<BOPAlgo_FillIn3DParts> \
|
||||
BOPAlgo_VectorOfFillIn3DParts;
|
||||
//
|
||||
typedef BOPCol_ContextFunctor
|
||||
<BOPAlgo_FillIn3DParts,
|
||||
BOPAlgo_VectorOfFillIn3DParts,
|
||||
Handle(IntTools_Context),
|
||||
IntTools_Context> BOPCol_FillIn3DPartsFunctor;
|
||||
//
|
||||
typedef BOPCol_ContextCnt
|
||||
<BOPCol_FillIn3DPartsFunctor,
|
||||
BOPAlgo_VectorOfFillIn3DParts,
|
||||
Handle(IntTools_Context)> BOPAlgo_FillIn3DPartsCnt;
|
||||
//
|
||||
//=======================================================================
|
||||
// class: BOPAlgo_Builder
|
||||
//
|
||||
//=======================================================================
|
||||
@@ -540,156 +184,123 @@ void BOPAlgo_Builder::FillIn3DParts
|
||||
BOPCol_DataMapOfShapeShape& theDraftSolids,
|
||||
const BOPCol_BaseAllocator& )
|
||||
{
|
||||
Standard_Boolean bHasImage;
|
||||
Standard_Integer i, k, aNbS, aNbLIF, aNbFIN, aNbVSB, aNbVFIP;
|
||||
Handle(NCollection_BaseAllocator) aAlr0;
|
||||
TopoDS_Solid aSD;
|
||||
TopoDS_Iterator aIt;
|
||||
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
|
||||
// Find all faces that are IN solids
|
||||
|
||||
// Store boxes of the shapes into a map
|
||||
BOPCol_IndexedDataMapOfShapeBox aShapeBoxMap(1, anAlloc);
|
||||
|
||||
// Fence map
|
||||
BOPCol_MapOfShape aMFence(1, anAlloc);
|
||||
|
||||
// Get all faces
|
||||
TopTools_ListOfShape aLFaces(anAlloc);
|
||||
|
||||
Standard_Integer i, aNbS = myDS->NbSourceShapes();
|
||||
for (i = 0; i < aNbS; ++i)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType() != TopAbs_FACE)
|
||||
continue;
|
||||
|
||||
const TopoDS_Shape& aS = aSI.Shape();
|
||||
const TopTools_ListOfShape* pLSIm = myImages.Seek(aS);
|
||||
|
||||
if (pLSIm)
|
||||
{
|
||||
TopTools_ListIteratorOfListOfShape aItLSIm(*pLSIm);
|
||||
for (; aItLSIm.More(); aItLSIm.Next())
|
||||
{
|
||||
const TopoDS_Shape& aSIm = aItLSIm.Value();
|
||||
if (aMFence.Add(aSIm))
|
||||
aLFaces.Append(aSIm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aLFaces.Append(aS);
|
||||
aShapeBoxMap.Add(aS, aSI.Box());
|
||||
}
|
||||
}
|
||||
|
||||
BRep_Builder aBB;
|
||||
//
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI, aItLI1;
|
||||
BOPCol_ListIteratorOfListOfShape aItLS;
|
||||
//
|
||||
aAlr0=
|
||||
NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
//
|
||||
BOPCol_MapOfShape aMFence(100, aAlr0);
|
||||
BOPAlgo_VectorOfShapeBox aVSB(256, aAlr0);
|
||||
//
|
||||
theDraftSolids.Clear();
|
||||
//
|
||||
// 1. aVSB vector Index/FaceBox
|
||||
aNbS=myDS->NbSourceShapes();
|
||||
for (i=0; i<aNbS; ++i) {
|
||||
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType()!=TopAbs_FACE) {
|
||||
|
||||
// Get all solids
|
||||
TopTools_ListOfShape aLSolids(anAlloc);
|
||||
// Keep INTERNAL faces of the solids
|
||||
BOPCol_DataMapOfShapeListOfShape aSolidsIF(1, anAlloc);
|
||||
// Draft solids
|
||||
BOPCol_IndexedDataMapOfShapeShape aDraftSolid(1, anAlloc);
|
||||
|
||||
for (i = 0; i < aNbS; ++i)
|
||||
{
|
||||
BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i);
|
||||
if (aSI.ShapeType() != TopAbs_SOLID)
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const TopoDS_Shape& aS=aSI.Shape();
|
||||
//
|
||||
if (myImages.IsBound(aS)) {
|
||||
const BOPCol_ListOfShape& aLS=myImages.Find(aS);
|
||||
aItLS.Initialize(aLS);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aSx=aItLS.Value();
|
||||
if (!aMFence.Add(aSx)) {
|
||||
continue;
|
||||
}
|
||||
Bnd_Box aBox;
|
||||
BRepBndLib::Add(aSx, aBox);
|
||||
aBox.SetGap(aBox.GetGap() + Precision::Confusion());
|
||||
//
|
||||
BOPAlgo_ShapeBox& aSB=aVSB.Append1();
|
||||
aSB.SetShape(aSx);
|
||||
aSB.SetBox(aBox);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const Bnd_Box& aBox=aSI.Box();
|
||||
//
|
||||
BOPAlgo_ShapeBox& aSB=aVSB.Append1();
|
||||
aSB.SetShape(aS);
|
||||
aSB.SetBox(aBox);
|
||||
}
|
||||
}//for (i=0; i<aNbS; ++i) {
|
||||
aMFence.Clear();
|
||||
//
|
||||
// 1.2. Prepare TreeFiller
|
||||
BOPCol_BoxBndTree aBBTree;
|
||||
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box>
|
||||
aTreeFiller(aBBTree);
|
||||
//
|
||||
aNbVSB=aVSB.Extent();
|
||||
for (k=0; k<aNbVSB; ++k) {
|
||||
const BOPAlgo_ShapeBox& aSBk=aVSB(k);
|
||||
const Bnd_Box& aBk=aSBk.Box();
|
||||
//
|
||||
aTreeFiller.Add(k, aBk);
|
||||
}
|
||||
//
|
||||
// 1.3. Shake TreeFiller
|
||||
aTreeFiller.Fill();
|
||||
//
|
||||
//---------------------------------------------
|
||||
// 2. Solids
|
||||
BOPAlgo_VectorOfFillIn3DParts aVFIP;
|
||||
//
|
||||
for (i=0; i<aNbS; ++i) {
|
||||
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType()!=TopAbs_SOLID) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const TopoDS_Shape& aS=aSI.Shape();
|
||||
const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
|
||||
//
|
||||
// 2.0 Flag bHasImage
|
||||
bHasImage=Standard_False;
|
||||
aIt.Initialize(aS);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aShell=aIt.Value();
|
||||
bHasImage=myImages.IsBound(aShell);
|
||||
if (bHasImage){
|
||||
break;
|
||||
}
|
||||
}
|
||||
//
|
||||
// 2.1 Bounding box for the solid aS [ aBoxS ]
|
||||
Bnd_Box aBoxS;
|
||||
aBoxS=aSI.Box();
|
||||
//
|
||||
// 2.2 Build Draft Solid [aSD]
|
||||
BOPCol_ListOfShape aLIF;
|
||||
|
||||
const TopoDS_Shape& aS = aSI.Shape();
|
||||
const TopoDS_Solid& aSolid = (*(TopoDS_Solid*)(&aS));
|
||||
//
|
||||
// Bounding box for the solid aS
|
||||
const Bnd_Box& aBoxS = aSI.Box();
|
||||
|
||||
// Build Draft Solid
|
||||
TopTools_ListOfShape aLIF;
|
||||
TopoDS_Solid aSD;
|
||||
aBB.MakeSolid(aSD);
|
||||
BuildDraftSolid(aSolid, aSD, aLIF);
|
||||
//
|
||||
BOPAlgo_FillIn3DParts& aFIP=aVFIP.Append1();
|
||||
//
|
||||
aFIP.SetSolid(aSolid);
|
||||
aFIP.SetDraftSolid(aSD);
|
||||
aFIP.SetHasImage(bHasImage);
|
||||
aFIP.SetBoxS(aBoxS);
|
||||
aFIP.SetLIF(aLIF);
|
||||
aFIP.SetBBTree(aBBTree);
|
||||
aFIP.SetVSB(aVSB);
|
||||
}//for (i=0; i<aNbS; ++i) {
|
||||
//
|
||||
aNbVFIP=aVFIP.Extent();
|
||||
//================================================================
|
||||
BOPAlgo_FillIn3DPartsCnt::Perform(myRunParallel, aVFIP, myContext);
|
||||
//================================================================
|
||||
for (k=0; k<aNbVFIP; ++k) {
|
||||
BOPAlgo_FillIn3DParts& aFIP=aVFIP(k);
|
||||
bHasImage=aFIP.HasImage();
|
||||
const TopoDS_Solid& aSolid=aFIP.Solid();
|
||||
const TopoDS_Solid& aSDraft =aFIP.DraftSolid();
|
||||
const BOPCol_ListOfShape& aLFIN=aFIP.LFIN();
|
||||
const BOPCol_ListOfShape& aLIF=aFIP.LIF();
|
||||
//
|
||||
aNbLIF=aLIF.Extent();
|
||||
//
|
||||
// Store the results in theInParts, theDraftSolids
|
||||
BOPCol_ListOfShape aLFINx;
|
||||
//
|
||||
aNbFIN=aLFIN.Extent();
|
||||
if (aNbFIN || aNbLIF) {
|
||||
aItLS.Initialize(aLFIN);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFI=aItLS.Value();
|
||||
aLFINx.Append(aFI);
|
||||
|
||||
aLSolids.Append(aSD);
|
||||
aSolidsIF.Bind(aSD, aLIF);
|
||||
aShapeBoxMap.Add(aSD, aBoxS);
|
||||
aDraftSolid.Add(aS, aSD);
|
||||
}
|
||||
aItLS.Initialize(aLIF);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aFI=aItLS.Value();
|
||||
aLFINx.Append(aFI);
|
||||
|
||||
// Perform classification of the faces
|
||||
TopTools_IndexedDataMapOfShapeListOfShape anInParts;
|
||||
|
||||
BOPAlgo_Tools::ClassifyFaces(aLFaces, aLSolids, myRunParallel,
|
||||
myContext, anInParts, &aShapeBoxMap, &aSolidsIF);
|
||||
|
||||
// Analyze the results of classification
|
||||
Standard_Integer aNbSol = aDraftSolid.Extent();
|
||||
for (i = 1; i <= aNbSol; ++i)
|
||||
{
|
||||
const TopoDS_Solid& aSolid = TopoDS::Solid(aDraftSolid.FindKey(i));
|
||||
const TopoDS_Solid& aSDraft = TopoDS::Solid(aDraftSolid(i));
|
||||
const TopTools_ListOfShape& aLInFaces = anInParts.FindFromKey(aSDraft);
|
||||
const TopTools_ListOfShape& aLInternal = aSolidsIF.Find(aSDraft);
|
||||
|
||||
Standard_Integer aNbIN = aLInFaces.Extent();
|
||||
|
||||
if (!aNbIN)
|
||||
{
|
||||
Standard_Boolean bHasImage = Standard_False;
|
||||
// Check if the shells of the solid have image
|
||||
for (TopoDS_Iterator it(aSolid); it.More() && !bHasImage; it.Next())
|
||||
bHasImage = myImages.IsBound(it.Value());
|
||||
|
||||
if (!bHasImage)
|
||||
// no need to split the solid
|
||||
continue;
|
||||
}
|
||||
theInParts.Bind(aSolid, aLFINx);
|
||||
}
|
||||
//
|
||||
if (aNbFIN || bHasImage) {
|
||||
|
||||
theDraftSolids.Bind(aSolid, aSDraft);
|
||||
|
||||
Standard_Integer aNbInt = aLInternal.Extent();
|
||||
if (aNbInt || aNbIN)
|
||||
{
|
||||
// Combine the lists
|
||||
TopTools_ListOfShape *pLIN = theInParts.Bound(aSolid, TopTools_ListOfShape());
|
||||
|
||||
TopTools_ListIteratorOfListOfShape aItLS(aLInFaces);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
pLIN->Append(aItLS.Value());
|
||||
|
||||
aItLS.Initialize(aLInternal);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
pLIN->Append(aItLS.Value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -54,7 +54,8 @@ BOPAlgo_PaveFiller::BOPAlgo_PaveFiller()
|
||||
BOPAlgo_PaveFiller::BOPAlgo_PaveFiller
|
||||
(const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
:
|
||||
BOPAlgo_Algo(theAllocator)
|
||||
BOPAlgo_Algo(theAllocator),
|
||||
myFPBDone(1, theAllocator)
|
||||
{
|
||||
myDS = NULL;
|
||||
myIterator = NULL;
|
||||
@@ -286,6 +287,13 @@ void BOPAlgo_PaveFiller::PerformInternal()
|
||||
UpdatePaveBlocksWithSDVertices();
|
||||
UpdateInterfsWithSDVertices();
|
||||
//
|
||||
// Force intersection of edges after increase
|
||||
// of the tolerance values of their vertices
|
||||
//ForceInterfEE();
|
||||
// Force Edge/Face intersection after increase
|
||||
// of the tolerance values of their vertices
|
||||
ForceInterfEF();
|
||||
//
|
||||
// 22
|
||||
PerformFF();
|
||||
if (HasErrors()) {
|
||||
|
@@ -167,6 +167,9 @@ protected:
|
||||
Bnd_Box,
|
||||
TColStd_MapTransientHasher> BOPAlgo_DataMapOfPaveBlockBndBox;
|
||||
|
||||
typedef NCollection_DataMap
|
||||
<Standard_Integer,
|
||||
BOPDS_MapOfPaveBlock> BOPAlgo_DataMapOfIntegerMapOfPaveBlock;
|
||||
|
||||
//! Sets non-destructive mode automatically if an argument
|
||||
//! contains a locked sub-shape (see TopoDS_Shape::Locked()).
|
||||
@@ -474,6 +477,19 @@ protected:
|
||||
//! In case self-interference is found the warning is added.
|
||||
Standard_EXPORT void CheckSelfInterference();
|
||||
|
||||
//! The method looks for the additional common blocks among pairs of edges
|
||||
//! with the same bounding vertices.
|
||||
Standard_EXPORT void ForceInterfEE();
|
||||
|
||||
//! The method looks for the additional edge/face common blocks
|
||||
//! among pairs of edge/face having the same vertices.
|
||||
Standard_EXPORT void ForceInterfEF();
|
||||
|
||||
//! Performs intersection of given pave blocks
|
||||
//! with all faces from arguments.
|
||||
Standard_EXPORT void ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
|
||||
const Standard_Boolean theAddInterf);
|
||||
|
||||
|
||||
BOPCol_ListOfShape myArguments;
|
||||
BOPDS_PDS myDS;
|
||||
@@ -485,6 +501,8 @@ protected:
|
||||
Standard_Boolean myAvoidBuildPCurve;
|
||||
BOPAlgo_GlueEnum myGlue;
|
||||
|
||||
BOPAlgo_DataMapOfIntegerMapOfPaveBlock myFPBDone; //!< Fence map of intersected faces and pave blocks
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
@@ -768,3 +768,278 @@ Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE,
|
||||
}
|
||||
return bValid;
|
||||
}
|
||||
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ForceInterfEE
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_PaveFiller::ForceInterfEE()
|
||||
{
|
||||
// Now that we have vertices increased and unified, try to find additional
|
||||
// common blocks among the pairs of edges.
|
||||
// Since all real intersections should have already happened, here we
|
||||
// are interested in common blocks only, thus we need to check only
|
||||
// those pairs of pave blocks with the same bounding vertices.
|
||||
|
||||
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
|
||||
// Initialize pave blocks for all vertices which participated in intersections
|
||||
const Standard_Integer aNbS = myDS->NbSourceShapes();
|
||||
for (Standard_Integer i = 0; i < aNbS; ++i)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType() == TopAbs_VERTEX)
|
||||
{
|
||||
if (myDS->HasInterf(i))
|
||||
myDS->InitPaveBlocksForVertex(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the connection map from bounding vertices to pave blocks
|
||||
// having those bounding vertices
|
||||
NCollection_IndexedDataMap<BOPDS_Pair,
|
||||
BOPDS_ListOfPaveBlock,
|
||||
BOPDS_PairMapHasher> aPBMap(1, anAlloc);
|
||||
// Fence map of pave blocks
|
||||
BOPDS_MapOfPaveBlock aMPBFence(1, anAlloc);
|
||||
|
||||
for (Standard_Integer i = 0; i < aNbS; ++i)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType() != TopAbs_EDGE)
|
||||
// Not an edge
|
||||
continue;
|
||||
|
||||
if (!aSI.HasReference())
|
||||
// Edge has no pave blocks
|
||||
continue;
|
||||
|
||||
if (aSI.HasFlag())
|
||||
// Degenerated edge
|
||||
continue;
|
||||
|
||||
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(i);
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
|
||||
for (; aItLPB.More(); aItLPB.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
|
||||
const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
|
||||
if (!aMPBFence.Add(aPBR))
|
||||
continue;
|
||||
|
||||
// Get indices
|
||||
Standard_Integer nV1, nV2;
|
||||
aPBR->Indices(nV1, nV2);
|
||||
|
||||
// Add pave block to a map
|
||||
BOPDS_Pair aPair(nV1, nV2);
|
||||
BOPDS_ListOfPaveBlock *pList = aPBMap.ChangeSeek(aPair);
|
||||
if (!pList)
|
||||
pList = &aPBMap(aPBMap.Add(aPair, BOPDS_ListOfPaveBlock(anAlloc)));
|
||||
pList->Append(aPBR);
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer aNbPB = aPBMap.Extent();
|
||||
if (!aNbPB)
|
||||
return;
|
||||
|
||||
const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
|
||||
|
||||
// Prepare pave blocks with the same vertices for intersection.
|
||||
BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
|
||||
|
||||
for (Standard_Integer i = 1; i <= aNbPB; ++i)
|
||||
{
|
||||
const BOPDS_ListOfPaveBlock& aLPB = aPBMap(i);
|
||||
if (aLPB.Extent() < 2)
|
||||
continue;
|
||||
|
||||
const BOPDS_Pair& aPair = aPBMap.FindKey(i);
|
||||
Standard_Integer nV1, nV2;
|
||||
aPair.Indices(nV1, nV2);
|
||||
|
||||
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
|
||||
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
|
||||
|
||||
// Use the max tolerance of vertices as Fuzzy value for intersection of edges.
|
||||
// In the Self-Interference check mode we are interested in real
|
||||
// intersections only, so use only the real tolerance of edges,
|
||||
// no need to use the extended tolerance.
|
||||
Standard_Real aTolAdd = (bSICheckMode ? myFuzzyValue :
|
||||
2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
|
||||
|
||||
// All possible pairs combined from the list <aLPB> should be checked
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB1(aLPB);
|
||||
for (; aItLPB1.More(); aItLPB1.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB1.Value();
|
||||
const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPB1);
|
||||
const Standard_Integer nE1 = aPB1->OriginalEdge();
|
||||
const Standard_Integer iR1 = myDS->Rank(nE1);
|
||||
const TopoDS_Edge& aE1 = TopoDS::Edge(myDS->Shape(nE1));
|
||||
Standard_Real aT11, aT12;
|
||||
aPB1->Range(aT11, aT12);
|
||||
BRepAdaptor_Curve aBAC1(aE1);
|
||||
gp_Pnt aPm;
|
||||
gp_Vec aVTgt1;
|
||||
aBAC1.D1((aT11 + aT12) * 0.5, aPm, aVTgt1);
|
||||
if (aVTgt1.SquareMagnitude() < gp::Resolution())
|
||||
continue;
|
||||
aVTgt1.Normalize();
|
||||
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB2 = aItLPB1;
|
||||
for (aItLPB2.Next(); aItLPB2.More(); aItLPB2.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB2 = aItLPB2.Value();
|
||||
const Handle(BOPDS_CommonBlock)& aCB2 = myDS->CommonBlock(aPB2);
|
||||
const Standard_Integer nE2 = aPB2->OriginalEdge();
|
||||
const Standard_Integer iR2 = myDS->Rank(nE2);
|
||||
|
||||
// Check that the edges came from different arguments
|
||||
if (iR1 == iR2)
|
||||
{
|
||||
// If the sharing of the vertices is not original, but has been acquired
|
||||
// during the operation, check the coincidence of the edges even if
|
||||
// they came from the same argument
|
||||
if ((!myDS->IsNewShape(nV1) && (myDS->Rank(nV1) == iR1)) ||
|
||||
(!myDS->IsNewShape(nV2) && (myDS->Rank(nV2) == iR2)))
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check that the Pave blocks do not form the Common block already
|
||||
if (!aCB1.IsNull() && !aCB2.IsNull())
|
||||
{
|
||||
if (aCB1 == aCB2)
|
||||
continue;
|
||||
}
|
||||
|
||||
const TopoDS_Edge& aE2 = TopoDS::Edge(myDS->Shape(nE2));
|
||||
Standard_Real aT21, aT22;
|
||||
aPB2->Range(aT21, aT22);
|
||||
|
||||
// Check the angle between edges in the middle point.
|
||||
// If the angle is more than 10 degrees, do not use the additional
|
||||
// tolerance, as it may lead to undesired unification of edges
|
||||
Standard_Boolean bUseAddTol = Standard_True;
|
||||
{
|
||||
BRepAdaptor_Curve aBAC2(aE2);
|
||||
if (aBAC1.GetType() != GeomAbs_Line ||
|
||||
aBAC2.GetType() != GeomAbs_Line)
|
||||
{
|
||||
GeomAPI_ProjectPointOnCurve& aProjPC = myContext->ProjPC(aE2);
|
||||
aProjPC.Perform(aPm);
|
||||
if (!aProjPC.NbPoints())
|
||||
continue;
|
||||
|
||||
gp_Pnt aPm2;
|
||||
gp_Vec aVTgt2;
|
||||
aBAC2.D1(aProjPC.LowerDistanceParameter(), aPm2, aVTgt2);
|
||||
if (aVTgt2.SquareMagnitude() < gp::Resolution())
|
||||
continue;
|
||||
|
||||
// The angle should be close to zero
|
||||
Standard_Real aCos = aVTgt1.Dot (aVTgt2.Normalized());
|
||||
if (Abs(aCos) < 0.9848)
|
||||
bUseAddTol = Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// Add pair for intersection
|
||||
BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge.Append1();
|
||||
anEdgeEdge.UseQuickCoincidenceCheck(Standard_True);
|
||||
anEdgeEdge.SetPaveBlock1(aPB1);
|
||||
anEdgeEdge.SetPaveBlock2(aPB2);
|
||||
anEdgeEdge.SetEdge1(aE1, aT11, aT12);
|
||||
anEdgeEdge.SetEdge2(aE2, aT21, aT22);
|
||||
//anEdgeEdge.SetBoxes (myDS->ShapeInfo(nE1).Box(), myDS->ShapeInfo (nE2).Box());
|
||||
if (bUseAddTol)
|
||||
anEdgeEdge.SetFuzzyValue(myFuzzyValue + aTolAdd);
|
||||
else
|
||||
anEdgeEdge.SetFuzzyValue(myFuzzyValue);
|
||||
anEdgeEdge.SetProgressIndicator(myProgressIndicator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer aNbPairs = aVEdgeEdge.Length();
|
||||
if (!aNbPairs)
|
||||
return;
|
||||
|
||||
aPBMap.Clear();
|
||||
aMPBFence.Clear();
|
||||
anAlloc->Reset();
|
||||
|
||||
// Perform intersection of the found pairs
|
||||
BOPAlgo_EdgeEdgeCnt::Perform (myRunParallel, aVEdgeEdge);
|
||||
|
||||
BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
|
||||
if (aEEs.IsEmpty())
|
||||
aEEs.SetIncrement(10);
|
||||
|
||||
// Analyze the results of intersection looking for TopAbs_EDGE
|
||||
// intersection type only.
|
||||
|
||||
BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(1, anAlloc);
|
||||
|
||||
for (Standard_Integer i = 0; i < aNbPairs; ++i)
|
||||
{
|
||||
BOPAlgo_EdgeEdge& anEdgeEdge = aVEdgeEdge(i);
|
||||
if (!anEdgeEdge.IsDone() || anEdgeEdge.HasErrors())
|
||||
{
|
||||
// Warn about failed intersection of sub-shapes
|
||||
//const TopoDS_Shape& aE1 = myDS->Shape(anEdgeEdge.PaveBlock1()->OriginalEdge());
|
||||
//const TopoDS_Shape& aE2 = myDS->Shape(anEdgeEdge.PaveBlock2()->OriginalEdge());
|
||||
//AddIntersectionFailedWarning(aE1, aE2);
|
||||
continue;
|
||||
}
|
||||
|
||||
const IntTools_SequenceOfCommonPrts& aCParts = anEdgeEdge.CommonParts();
|
||||
if (aCParts.Length() != 1)
|
||||
continue;
|
||||
|
||||
const IntTools_CommonPrt& aCP = aCParts(1);
|
||||
if (aCP.Type() != TopAbs_EDGE)
|
||||
continue;
|
||||
|
||||
Handle(BOPDS_PaveBlock) aPB[] = {anEdgeEdge.PaveBlock1(), anEdgeEdge.PaveBlock2()};
|
||||
const Standard_Integer nE1 = aPB[0]->OriginalEdge();
|
||||
const Standard_Integer nE2 = aPB[1]->OriginalEdge();
|
||||
|
||||
if (myDS->Rank(nE1) == myDS->Rank(nE2))
|
||||
{
|
||||
// Add acquired self-interference warning
|
||||
//TopoDS_Compound aWC;
|
||||
//BRep_Builder().MakeCompound(aWC);
|
||||
//BRep_Builder().Add(aWC, myDS->Shape(nE1));
|
||||
//BRep_Builder().Add(aWC, myDS->Shape(nE2));
|
||||
//AddWarning(new BOPAlgo_AlertAcquiredSelfIntersection(aWC));
|
||||
}
|
||||
|
||||
BOPDS_InterfEE& aEE = aEEs.Append1();
|
||||
aEE.SetIndices(nE1, nE2);
|
||||
aEE.SetCommonPart(aCP);
|
||||
myDS->AddInterf(nE1, nE2);
|
||||
|
||||
// Fill map for common blocks creation
|
||||
for (Standard_Integer j = 0; j < 2; ++j)
|
||||
{
|
||||
if (myDS->IsCommonBlock(aPB[j]))
|
||||
{
|
||||
const BOPDS_ListOfPaveBlock& aLPBCB = myDS->CommonBlock(aPB[j])->PaveBlocks();
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBCB);
|
||||
for (; aItLPB.More(); aItLPB.Next())
|
||||
BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock),
|
||||
TColStd_MapTransientHasher>(aPB[j], aItLPB.Value(), aMPBLPB, anAlloc);
|
||||
}
|
||||
}
|
||||
BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock),
|
||||
TColStd_MapTransientHasher>(aPB[0], aPB[1], aMPBLPB, anAlloc);
|
||||
}
|
||||
|
||||
// Create new common blocks of coinciding pairs.
|
||||
BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, anAlloc, myDS);
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include <BOPAlgo_PaveFiller.hxx>
|
||||
#include <BOPAlgo_Alerts.hxx>
|
||||
#include <BOPAlgo_Tools.hxx>
|
||||
#include <BOPCol_BoxBndTree.hxx>
|
||||
#include <BOPCol_MapOfInteger.hxx>
|
||||
#include <BOPCol_NCVector.hxx>
|
||||
#include <BOPCol_Parallel.hxx>
|
||||
@@ -33,9 +34,11 @@
|
||||
#include <BOPDS_Pave.hxx>
|
||||
#include <BOPDS_PaveBlock.hxx>
|
||||
#include <BOPTools_AlgoTools.hxx>
|
||||
#include <BOPTools_AlgoTools2D.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <IntTools_CommonPrt.hxx>
|
||||
#include <IntTools_Context.hxx>
|
||||
@@ -43,12 +46,15 @@
|
||||
#include <IntTools_Range.hxx>
|
||||
#include <IntTools_SequenceOfCommonPrts.hxx>
|
||||
#include <IntTools_Tools.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_UBTreeFiller.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_EdgeFace
|
||||
//purpose :
|
||||
@@ -247,7 +253,12 @@ void BOPAlgo_PaveFiller::PerformEF()
|
||||
BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
|
||||
aEdgeFace.SetRange (aPBRange);
|
||||
aEdgeFace.SetProgressIndicator(myProgressIndicator);
|
||||
//
|
||||
|
||||
// Save the pair to avoid their forced intersection
|
||||
BOPDS_MapOfPaveBlock* pMPB = myFPBDone.ChangeSeek(nF);
|
||||
if (!pMPB)
|
||||
pMPB = myFPBDone.Bound(nF, BOPDS_MapOfPaveBlock());
|
||||
pMPB->Add(aPB);
|
||||
}//for (; aIt.More(); aIt.Next()) {
|
||||
}//for (; myIterator->More(); myIterator->Next()) {
|
||||
//
|
||||
@@ -656,3 +667,351 @@ void BOPAlgo_PaveFiller::ReduceIntersectionRange(const Standard_Integer theV1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ForceInterfEF
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_PaveFiller::ForceInterfEF()
|
||||
{
|
||||
if (!myIsPrimary)
|
||||
return;
|
||||
|
||||
// Now that we have vertices increased and unified, try to find additional
|
||||
// edge/face common blocks among the pairs of edge/face.
|
||||
// Here, we are interested in common blocks only, as all real intersections
|
||||
// should have happened already. Thus, we need to check only those pairs
|
||||
// of edge/face which have the same vertices.
|
||||
|
||||
// Collect all pave blocks
|
||||
BOPDS_IndexedMapOfPaveBlock aMPB;
|
||||
const Standard_Integer aNbS = myDS->NbSourceShapes();
|
||||
for (Standard_Integer nE = 0; nE < aNbS; ++nE)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nE);
|
||||
if (aSI.ShapeType() != TopAbs_EDGE)
|
||||
// Not an edge
|
||||
continue;
|
||||
|
||||
if (!aSI.HasReference())
|
||||
// Edge has no pave blocks
|
||||
continue;
|
||||
|
||||
if (aSI.HasFlag())
|
||||
// Degenerated edge
|
||||
continue;
|
||||
|
||||
const BOPDS_ListOfPaveBlock& aLPB = myDS->PaveBlocks(nE);
|
||||
BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
|
||||
for (; aItLPB.More(); aItLPB.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
|
||||
const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
|
||||
aMPB.Add(aPBR);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform intersection of collected pave blocks with faces
|
||||
ForceInterfEF(aMPB, Standard_True);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ForceInterfEF
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB,
|
||||
const Standard_Boolean theAddInterf)
|
||||
{
|
||||
if (theMPB.IsEmpty())
|
||||
return;
|
||||
|
||||
// Fill the tree with bounding boxes of the pave blocks
|
||||
NCollection_UBTree<Standard_Integer, Bnd_Box> aBBTree;
|
||||
NCollection_UBTreeFiller<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
|
||||
|
||||
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
BOPDS_IndexedMapOfPaveBlock aPBMap(1, anAlloc);
|
||||
|
||||
Standard_Integer aNbPB = theMPB.Extent();
|
||||
for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB)
|
||||
{
|
||||
Handle(BOPDS_PaveBlock) aPB = theMPB(iPB);
|
||||
if (!aPB->HasShrunkData() || !myDS->IsValidShrunkData(aPB))
|
||||
{
|
||||
FillShrunkData(aPB);
|
||||
if (!aPB->HasShrunkData())
|
||||
continue;
|
||||
}
|
||||
|
||||
Standard_Real f, l;
|
||||
Bnd_Box aPBBox;
|
||||
Standard_Boolean isSplit;
|
||||
aPB->ShrunkData(f, l, aPBBox, isSplit);
|
||||
|
||||
aTreeFiller.Add(aPBMap.Add(aPB), aPBBox);
|
||||
}
|
||||
|
||||
// Shake the tree
|
||||
aTreeFiller.Fill();
|
||||
|
||||
const Standard_Boolean bSICheckMode = (myArguments.Extent() == 1);
|
||||
|
||||
// Find pairs of Face/PaveBlock containing the same vertices
|
||||
// and prepare those pairs for intersection.
|
||||
BOPAlgo_VectorOfEdgeFace aVEdgeFace;
|
||||
|
||||
const Standard_Integer aNbS = myDS->NbSourceShapes();
|
||||
for (Standard_Integer nF = 0; nF < aNbS; ++nF)
|
||||
{
|
||||
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
|
||||
if (aSI.ShapeType() != TopAbs_FACE)
|
||||
// Not a face
|
||||
continue;
|
||||
|
||||
if (!aSI.HasReference())
|
||||
// Face has no face info
|
||||
continue;
|
||||
|
||||
const Bnd_Box& aBoxF = aSI.Box();
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
aSelector.SetBox(aBoxF);
|
||||
|
||||
if (!aBBTree.Select(aSelector))
|
||||
continue;
|
||||
|
||||
const TopoDS_Face& aF = TopoDS::Face(aSI.Shape());
|
||||
const BOPDS_FaceInfo& aFI = myDS->FaceInfo(nF);
|
||||
// Vertices of the face
|
||||
BOPCol_MapOfInteger aMVF;
|
||||
const BOPCol_MapOfInteger* pMVF[] = { &aFI.VerticesOn(),
|
||||
&aFI.VerticesIn(),
|
||||
&aFI.VerticesSc() };
|
||||
for (Standard_Integer iM = 0; iM < 3; ++iM)
|
||||
{
|
||||
BOPCol_MapIteratorOfMapOfInteger itM(*pMVF[iM]);
|
||||
for (; itM.More(); itM.Next())
|
||||
aMVF.Add(itM.Value());
|
||||
}
|
||||
|
||||
// Pave Blocks of the face
|
||||
const BOPDS_IndexedMapOfPaveBlock* pMPBF[] = { &aFI.PaveBlocksOn(),
|
||||
&aFI.PaveBlocksIn(),
|
||||
&aFI.PaveBlocksSc() };
|
||||
for (Standard_Integer iM = 0; iM < 3; ++iM)
|
||||
{
|
||||
const Standard_Integer aNb = pMPBF[iM]->Extent();
|
||||
for (Standard_Integer iPB = 1; iPB <= aNb; ++iPB)
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = pMPBF[iM]->FindKey(iPB);
|
||||
aMVF.Add(aPB->Pave1().Index());
|
||||
aMVF.Add(aPB->Pave2().Index());
|
||||
}
|
||||
}
|
||||
|
||||
// Projection tool
|
||||
GeomAPI_ProjectPointOnSurf& aProjPS = myContext->ProjPS(aF);
|
||||
BRepAdaptor_Surface& aSurfAdaptor = myContext->SurfaceAdaptor (aF);
|
||||
|
||||
// Iterate on pave blocks and combine pairs containing
|
||||
// the same vertices
|
||||
const BOPCol_ListOfInteger& aLIPB = aSelector.Indices();
|
||||
BOPCol_ListOfInteger::Iterator itLIPB(aLIPB);
|
||||
for (; itLIPB.More(); itLIPB.Next())
|
||||
{
|
||||
const Handle(BOPDS_PaveBlock)& aPB = aPBMap(itLIPB.Value());
|
||||
if (pMPBF[0]->Contains(aPB) ||
|
||||
pMPBF[1]->Contains(aPB) ||
|
||||
pMPBF[2]->Contains(aPB))
|
||||
continue;
|
||||
|
||||
// Check if the face contains both vertices of the pave block
|
||||
Standard_Integer nV1, nV2;
|
||||
aPB->Indices(nV1, nV2);
|
||||
if (!aMVF.Contains(nV1) || !aMVF.Contains(nV2))
|
||||
// Face does not contain the vertices
|
||||
continue;
|
||||
|
||||
// Get the edge
|
||||
Standard_Integer nE;
|
||||
if (!aPB->HasEdge(nE))
|
||||
{
|
||||
nE = aPB->OriginalEdge();
|
||||
if (nE < 0)
|
||||
continue;
|
||||
|
||||
// Make sure that the edge and face came from different arguments
|
||||
if (myDS->Rank(nF) == myDS->Rank(nE))
|
||||
continue;
|
||||
}
|
||||
|
||||
const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
|
||||
BRepAdaptor_Curve aBAC(aE);
|
||||
|
||||
// Check directions coincidence at middle point on the edge
|
||||
// and projection of that point on the face.
|
||||
// If the angle between tangent vector to the curve and normal
|
||||
// of the face is not in the range of 65 - 115 degrees, do not use the additional
|
||||
// tolerance, as it may lead to undesired unification of edge with the face.
|
||||
Standard_Boolean bUseAddTol = Standard_True;
|
||||
|
||||
Standard_Real aTS[2];
|
||||
Bnd_Box aPBBox;
|
||||
Standard_Boolean isSplit;
|
||||
aPB->ShrunkData(aTS[0], aTS[1], aPBBox, isSplit);
|
||||
|
||||
// Middle point
|
||||
gp_Pnt aPOnE;
|
||||
// Tangent vector in the middle point
|
||||
gp_Vec aVETgt;
|
||||
aBAC.D1(BOPTools_AlgoTools2D::IntermediatePoint(aTS[0], aTS[1]), aPOnE, aVETgt);
|
||||
if (aVETgt.SquareMagnitude() < gp::Resolution())
|
||||
continue;
|
||||
|
||||
aProjPS.Perform(aPOnE);
|
||||
if (!aProjPS.NbPoints())
|
||||
continue;
|
||||
|
||||
// Check the distance in the middle point, using the max vertices
|
||||
// tolerance as the criteria.
|
||||
const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(nV1));
|
||||
const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(nV2));
|
||||
|
||||
// In the Self-Interference check mode we are interested in real
|
||||
// intersections only, so use only the real tolerance of edges,
|
||||
// no need to use the extended tolerance.
|
||||
Standard_Real aTolCheck = (bSICheckMode ? myFuzzyValue :
|
||||
2 * Max(BRep_Tool::Tolerance(aV1), BRep_Tool::Tolerance(aV2)));
|
||||
|
||||
if (aProjPS.LowerDistance() > aTolCheck + myFuzzyValue)
|
||||
continue;
|
||||
|
||||
Standard_Real U, V;
|
||||
aProjPS.LowerDistanceParameters(U, V);
|
||||
if (!myContext->IsPointInFace(aF, gp_Pnt2d(U, V)))
|
||||
continue;
|
||||
|
||||
if (aSurfAdaptor.GetType() != GeomAbs_Plane ||
|
||||
aBAC.GetType() != GeomAbs_Line)
|
||||
{
|
||||
gp_Pnt aPOnS = aProjPS.NearestPoint();
|
||||
gp_Vec aVFNorm(aPOnS, aPOnE);
|
||||
if (aVFNorm.SquareMagnitude() > gp::Resolution())
|
||||
{
|
||||
// Angle between vectors should be close to 90 degrees.
|
||||
// We allow deviation of 10 degrees.
|
||||
Standard_Real aCos = aVFNorm.Normalized().Dot (aVETgt.Normalized());
|
||||
if (Abs(aCos) > 0.17365)
|
||||
bUseAddTol = Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute an addition to Fuzzy value
|
||||
Standard_Real aTolAdd = 0.0;
|
||||
if (bUseAddTol)
|
||||
{
|
||||
// Compute the distance from the bounding points of the edge
|
||||
// to the face and use the maximal of these distances as a
|
||||
// fuzzy tolerance for the intersection.
|
||||
// Use the maximal tolerance of the pave block's vertices
|
||||
// as a max criteria for the computed distance.
|
||||
|
||||
for (Standard_Integer iP = 0; iP < 2; ++iP)
|
||||
{
|
||||
gp_Pnt aP = aBAC.Value(aTS[iP]);
|
||||
aProjPS.Perform(aP);
|
||||
if (aProjPS.NbPoints())
|
||||
{
|
||||
Standard_Real aDistEF = aProjPS.LowerDistance();
|
||||
if (aDistEF < aTolCheck && aDistEF > aTolAdd)
|
||||
aTolAdd = aDistEF;
|
||||
}
|
||||
}
|
||||
if (aTolAdd > 0.)
|
||||
{
|
||||
aTolAdd -= (BRep_Tool::Tolerance(aE) + BRep_Tool::Tolerance(aF));
|
||||
if (aTolAdd < 0.)
|
||||
aTolAdd = 0.;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean bIntersect = aTolAdd > 0;
|
||||
if (!bIntersect)
|
||||
{
|
||||
const BOPDS_MapOfPaveBlock* pMPB = myFPBDone.Seek(nF);
|
||||
bIntersect = !pMPB || !(pMPB->Contains(aPB));
|
||||
}
|
||||
|
||||
if (bIntersect)
|
||||
{
|
||||
// Prepare pair for intersection
|
||||
BOPAlgo_EdgeFace& aEdgeFace = aVEdgeFace.Append1();
|
||||
aEdgeFace.SetIndices(nE, nF);
|
||||
aEdgeFace.SetPaveBlock(aPB);
|
||||
aEdgeFace.SetEdge(aE);
|
||||
aEdgeFace.SetFace(aF);
|
||||
//aEdgeFace.SetBoxes (myDS->ShapeInfo(nE).Box(), myDS->ShapeInfo (nF).Box());
|
||||
aEdgeFace.SetFuzzyValue(myFuzzyValue + aTolAdd);
|
||||
aEdgeFace.UseQuickCoincidenceCheck(Standard_True);
|
||||
aEdgeFace.SetRange(IntTools_Range(aPB->Pave1().Parameter(), aPB->Pave2().Parameter()));
|
||||
aEdgeFace.SetProgressIndicator(myProgressIndicator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Integer aNbEFs = aVEdgeFace.Length();
|
||||
if (!aNbEFs)
|
||||
return;
|
||||
|
||||
aPBMap.Clear();
|
||||
anAlloc->Reset();
|
||||
|
||||
// Perform intersection of the found pairs
|
||||
BOPAlgo_EdgeFaceCnt::Perform (myRunParallel, aVEdgeFace, myContext);
|
||||
|
||||
BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
|
||||
if (theAddInterf && aEFs.IsEmpty())
|
||||
aEFs.SetIncrement(10);
|
||||
|
||||
// Analyze the results of intersection looking for TopAbs_EDGE
|
||||
// intersection type only.
|
||||
|
||||
// Collect all pairs for common block creation
|
||||
BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(1, anAlloc);
|
||||
|
||||
for (Standard_Integer i = 0; i < aNbEFs; ++i)
|
||||
{
|
||||
BOPAlgo_EdgeFace& anEdgeFace = aVEdgeFace(i);
|
||||
if (!anEdgeFace.IsDone() || anEdgeFace.HasErrors())
|
||||
continue;
|
||||
|
||||
const IntTools_SequenceOfCommonPrts& aCParts = anEdgeFace.CommonParts();
|
||||
if (aCParts.Length() != 1)
|
||||
continue;
|
||||
|
||||
const IntTools_CommonPrt& aCP = aCParts(1);
|
||||
if (aCP.Type() != TopAbs_EDGE)
|
||||
continue;
|
||||
|
||||
Standard_Integer nE, nF;
|
||||
anEdgeFace.Indices(nE, nF);
|
||||
if (theAddInterf)
|
||||
{
|
||||
// Add interference
|
||||
BOPDS_InterfEF& aEF = aEFs.Append1();
|
||||
aEF.SetIndices(nE, nF);
|
||||
aEF.SetCommonPart(aCP);
|
||||
myDS->AddInterf(nE, nF);
|
||||
}
|
||||
|
||||
const Handle(BOPDS_PaveBlock)& aPB = anEdgeFace.PaveBlock();
|
||||
// Update face information with new IN pave block
|
||||
myDS->ChangeFaceInfo(nF).ChangePaveBlocksIn().Add(aPB);
|
||||
if (theAddInterf)
|
||||
// Fill map for common blocks creation
|
||||
BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, anAlloc);
|
||||
}
|
||||
|
||||
if (aMPBLI.Extent())
|
||||
// Create new common blocks for coinciding pairs
|
||||
BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, anAlloc, myDS);
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Solid.hxx>
|
||||
|
||||
#include <BOPCol_BoxBndTree.hxx>
|
||||
#include <BOPCol_IndexedMapOfShape.hxx>
|
||||
@@ -38,6 +39,8 @@
|
||||
#include <BOPCol_NCVector.hxx>
|
||||
#include <BOPCol_Parallel.hxx>
|
||||
|
||||
#include <BRepBndLib.hxx>
|
||||
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
@@ -64,10 +67,13 @@
|
||||
#include <BOPTools_AlgoTools.hxx>
|
||||
#include <BOPTools_AlgoTools2D.hxx>
|
||||
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_UBTreeFiller.hxx>
|
||||
|
||||
#include <IntTools_Context.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
typedef NCollection_IndexedDataMap
|
||||
<TopoDS_Shape, gp_Dir, TopTools_ShapeMapHasher> BOPAlgo_IndexedDataMapOfShapeDir;
|
||||
typedef NCollection_IndexedDataMap
|
||||
@@ -1088,3 +1094,537 @@ void BOPAlgo_Tools::IntersectVertices(const BOPCol_IndexedDataMapOfShapeReal& th
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
// Classification of the faces relatively solids
|
||||
//=======================================================================
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_ShapeBox
|
||||
//purpose : Auxiliary class defining ShapeBox structure
|
||||
//=======================================================================
|
||||
class BOPAlgo_ShapeBox
|
||||
{
|
||||
public:
|
||||
//! Empty constructor
|
||||
BOPAlgo_ShapeBox() {};
|
||||
//! Sets the shape
|
||||
void SetShape(const TopoDS_Shape& theS)
|
||||
{
|
||||
myShape = theS;
|
||||
};
|
||||
//! Returns the shape
|
||||
const TopoDS_Shape& Shape() const
|
||||
{
|
||||
return myShape;
|
||||
};
|
||||
//! Sets the bounding box
|
||||
void SetBox(const Bnd_Box& theBox)
|
||||
{
|
||||
myBox = theBox;
|
||||
};
|
||||
//! Returns the bounding box
|
||||
const Bnd_Box& Box() const
|
||||
{
|
||||
return myBox;
|
||||
};
|
||||
private:
|
||||
TopoDS_Shape myShape;
|
||||
Bnd_Box myBox;
|
||||
};
|
||||
// Vector of ShapeBox
|
||||
typedef BOPCol_NCVector<BOPAlgo_ShapeBox> BOPAlgo_VectorOfShapeBox;
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_FillIn3DParts
|
||||
//purpose : Auxiliary class for faces classification in parallel mode
|
||||
//=======================================================================
|
||||
class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo
|
||||
{
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
//! Constructor
|
||||
BOPAlgo_FillIn3DParts()
|
||||
{
|
||||
myBBTree = NULL;
|
||||
myVShapeBox = NULL;
|
||||
};
|
||||
|
||||
//! Destructor
|
||||
virtual ~BOPAlgo_FillIn3DParts() {};
|
||||
|
||||
//! Sets the solid
|
||||
void SetSolid(const TopoDS_Solid& theSolid)
|
||||
{
|
||||
mySolid = theSolid;
|
||||
};
|
||||
|
||||
//! Returns the solid
|
||||
const TopoDS_Solid& Solid() const
|
||||
{
|
||||
return mySolid;
|
||||
};
|
||||
|
||||
//! Sets the box for the solid
|
||||
void SetBoxS(const Bnd_Box& theBox)
|
||||
{
|
||||
myBoxS = theBox;
|
||||
};
|
||||
|
||||
//! Returns the solid's box
|
||||
const Bnd_Box& BoxS() const
|
||||
{
|
||||
return myBoxS;
|
||||
};
|
||||
|
||||
//! Sets own INTERNAL faces of the solid
|
||||
void SetOwnIF(const BOPCol_ListOfShape& theLIF)
|
||||
{
|
||||
myOwnIF = theLIF;
|
||||
};
|
||||
|
||||
//! Returns own INTERNAL faces of the solid
|
||||
const BOPCol_ListOfShape& OwnIF() const
|
||||
{
|
||||
return myOwnIF;
|
||||
};
|
||||
|
||||
//! Sets the Bounding Box tree
|
||||
void SetBBTree(const BOPCol_BoxBndTree& theBBTree)
|
||||
{
|
||||
myBBTree = (BOPCol_BoxBndTree*)&theBBTree;
|
||||
};
|
||||
|
||||
//! Sets the ShapeBox structure
|
||||
void SetShapeBoxVector(const BOPAlgo_VectorOfShapeBox& theShapeBox)
|
||||
{
|
||||
myVShapeBox = (BOPAlgo_VectorOfShapeBox*)&theShapeBox;
|
||||
};
|
||||
|
||||
//! Sets the context
|
||||
void SetContext(const Handle(IntTools_Context)& theContext)
|
||||
{
|
||||
myContext = theContext;
|
||||
}
|
||||
|
||||
//! Returns the context
|
||||
const Handle(IntTools_Context)& Context() const
|
||||
{
|
||||
return myContext;
|
||||
}
|
||||
|
||||
//! Performs the classification
|
||||
virtual void Perform();
|
||||
|
||||
//! Returns the faces classified as IN for solid
|
||||
const BOPCol_ListOfShape& InFaces() const
|
||||
{
|
||||
return myInFaces;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
//! Prepares Edge-Face connection map of the given shape
|
||||
void MapEdgesAndFaces(const TopoDS_Shape& theF,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
|
||||
const Handle(NCollection_BaseAllocator)& theAlloc);
|
||||
|
||||
//! Makes the connexity block of faces using the connection map
|
||||
void MakeConnexityBlock(const TopoDS_Face& theF,
|
||||
const BOPCol_IndexedMapOfShape& theMEToAvoid,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
|
||||
BOPCol_MapOfShape& theMFDone,
|
||||
BOPCol_ListOfShape& theLCB,
|
||||
TopoDS_Face& theFaceToClassify);
|
||||
|
||||
TopoDS_Solid mySolid; //! Solid
|
||||
Bnd_Box myBoxS; // Bounding box of the solid
|
||||
BOPCol_ListOfShape myOwnIF; //! Own INTERNAL faces of the solid
|
||||
BOPCol_ListOfShape myInFaces; //! Faces classified as IN
|
||||
|
||||
BOPCol_BoxBndTree* myBBTree; //! UB tree of bounding boxes
|
||||
BOPAlgo_VectorOfShapeBox* myVShapeBox; //! ShapeBoxMap
|
||||
|
||||
TopoDS_Iterator myItF; //! Iterators
|
||||
TopoDS_Iterator myItW;
|
||||
|
||||
Handle(IntTools_Context) myContext; //! Context
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : BOPAlgo_FillIn3DParts::Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::Perform()
|
||||
{
|
||||
BOPAlgo_Algo::UserBreak();
|
||||
|
||||
myInFaces.Clear();
|
||||
|
||||
// 1. Select boxes of faces that are not out of aBoxS
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
aSelector.SetBox(myBoxS);
|
||||
//
|
||||
if (!myBBTree->Select(aSelector))
|
||||
return;
|
||||
|
||||
const BOPCol_ListOfInteger& aLIFP = aSelector.Indices();
|
||||
|
||||
// 2. Fill maps of edges and faces of the solid
|
||||
|
||||
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
|
||||
BOPAlgo_VectorOfShapeBox& aVShapeBox = *myVShapeBox;
|
||||
|
||||
BOPCol_IndexedMapOfShape aMSE(1, anAlloc), aMSF(1, anAlloc);
|
||||
BOPTools::MapShapes(mySolid, TopAbs_EDGE, aMSE);
|
||||
BOPTools::MapShapes(mySolid, TopAbs_FACE, aMSF);
|
||||
|
||||
// Check if the Solid contains any faces
|
||||
Standard_Boolean bIsEmpty = aMSF.IsEmpty();
|
||||
|
||||
// Add own internal faces of the solid into aMSF
|
||||
BOPCol_ListIteratorOfListOfShape aItLS(myOwnIF);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
aMSF.Add(aItLS.Value());
|
||||
|
||||
// 3. aIVec - faces to process.
|
||||
// Filter the selected faces with faces of the solid.
|
||||
BOPCol_NCVector<Standard_Integer> aIVec(256, anAlloc);
|
||||
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI(aLIFP);
|
||||
for (; aItLI.More(); aItLI.Next()) {
|
||||
Standard_Integer nFP = aItLI.Value();
|
||||
const TopoDS_Shape& aFP = aVShapeBox(nFP).Shape();
|
||||
if (!aMSF.Contains(aFP))
|
||||
aIVec.Append1() = nFP;
|
||||
}
|
||||
|
||||
// 4. Classify faces relatively solid.
|
||||
// Store faces that are IN mySolid into <myInFaces>
|
||||
|
||||
Standard_Integer k, aNbFP = aIVec.Length();
|
||||
// Sort indices if necessary
|
||||
if (aNbFP > 1)
|
||||
std::sort(aIVec.begin(), aIVec.end());
|
||||
|
||||
if (bIsEmpty)
|
||||
{
|
||||
// The solid is empty as it does not contain any faces.
|
||||
// It could happen when the input solid consists of INTERNAL faces only.
|
||||
// Classification of any point relatively empty solid would always give IN status.
|
||||
// Thus, we consider all selected faces as IN without real classification.
|
||||
for (k = 0; k < aNbFP; ++k)
|
||||
myInFaces.Append(aVShapeBox(aIVec(k)).Shape());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare EF map of faces to process for building connexity blocks
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEFP(1, anAlloc);
|
||||
if (aNbFP > 1)
|
||||
{
|
||||
for (k = 0; k < aNbFP; ++k)
|
||||
MapEdgesAndFaces(aVShapeBox(aIVec(k)).Shape(), aMEFP, anAlloc);
|
||||
}
|
||||
|
||||
// Map of Edge-Face connection, necessary for solid classification.
|
||||
// It will be filled when first classification is performed.
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEFDS(1, anAlloc);
|
||||
|
||||
// Fence map to avoid processing of the same faces twice
|
||||
BOPCol_MapOfShape aMFDone(1, anAlloc);
|
||||
|
||||
for (k = 0; k < aNbFP; ++k)
|
||||
{
|
||||
Standard_Integer nFP = aIVec(k);
|
||||
const TopoDS_Face& aFP = (*(TopoDS_Face*)&aVShapeBox(nFP).Shape());
|
||||
if (!aMFDone.Add(aFP))
|
||||
continue;
|
||||
|
||||
// Make connexity blocks of faces, avoiding passing through the
|
||||
// borders of the solid. It helps to reduce significantly the
|
||||
// number of classified faces.
|
||||
BOPCol_ListOfShape aLCBF(anAlloc);
|
||||
// The most appropriate face for classification
|
||||
TopoDS_Face aFaceToClassify;
|
||||
MakeConnexityBlock(aFP, aMSE, aMEFP, aMFDone, aLCBF, aFaceToClassify);
|
||||
|
||||
if (!myBoxS.IsWhole())
|
||||
{
|
||||
// First, try fast classification of the whole block by additional
|
||||
// check on bounding boxes - check that bounding boxes of all vertices
|
||||
// of the block interfere with the box of the solid.
|
||||
// If not, the faces are out.
|
||||
Standard_Boolean bOut = Standard_False;
|
||||
aItLS.Initialize(aLCBF);
|
||||
for (; aItLS.More() && !bOut; aItLS.Next())
|
||||
{
|
||||
TopExp_Explorer anExpV(aItLS.Value(), TopAbs_VERTEX);
|
||||
for (; anExpV.More() && !bOut; anExpV.Next())
|
||||
{
|
||||
const TopoDS_Vertex& aV = TopoDS::Vertex(anExpV.Current());
|
||||
Bnd_Box aBBV;
|
||||
aBBV.Add(BRep_Tool::Pnt(aV));
|
||||
aBBV.SetGap(BRep_Tool::Tolerance(aV));
|
||||
bOut = myBoxS.IsOut(aBBV);
|
||||
}
|
||||
}
|
||||
if (bOut)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (aFaceToClassify.IsNull())
|
||||
aFaceToClassify = aFP;
|
||||
|
||||
if (aMEFDS.IsEmpty())
|
||||
// Fill EF map for Solid
|
||||
BOPTools::MapShapesAndAncestors(mySolid, TopAbs_EDGE, TopAbs_FACE, aMEFDS);
|
||||
|
||||
// All vertices are interfere with the solids box, run classification.
|
||||
Standard_Boolean bIsIN = BOPTools_AlgoTools::IsInternalFace
|
||||
(aFaceToClassify, mySolid, aMEFDS, Precision::Confusion(), myContext);
|
||||
if (bIsIN)
|
||||
{
|
||||
aItLS.Initialize(aLCBF);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
myInFaces.Append(aItLS.Value());
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
// function: MapEdgesAndFaces
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::MapEdgesAndFaces(const TopoDS_Shape& theF,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
{
|
||||
myItF.Initialize(theF);
|
||||
for (; myItF.More(); myItF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aW = myItF.Value();
|
||||
if (aW.ShapeType() != TopAbs_WIRE)
|
||||
continue;
|
||||
|
||||
myItW.Initialize(aW);
|
||||
for (; myItW.More(); myItW.Next())
|
||||
{
|
||||
const TopoDS_Shape& aE = myItW.Value();
|
||||
|
||||
BOPCol_ListOfShape* pLF = theEFMap.ChangeSeek(aE);
|
||||
if (!pLF)
|
||||
pLF = &theEFMap(theEFMap.Add(aE, BOPCol_ListOfShape(theAllocator)));
|
||||
pLF->Append(theF);
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
// function: MakeConnexityBlock
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::MakeConnexityBlock(const TopoDS_Face& theFStart,
|
||||
const BOPCol_IndexedMapOfShape& theMEAvoid,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& theEFMap,
|
||||
BOPCol_MapOfShape& theMFDone,
|
||||
BOPCol_ListOfShape& theLCB,
|
||||
TopoDS_Face& theFaceToClassify)
|
||||
{
|
||||
// Add start element
|
||||
theLCB.Append(theFStart);
|
||||
if (theEFMap.IsEmpty())
|
||||
return;
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItCB(theLCB);
|
||||
for (; aItCB.More(); aItCB.Next())
|
||||
{
|
||||
const TopoDS_Shape& aF = aItCB.Value();
|
||||
myItF.Initialize(aF);
|
||||
for (; myItF.More(); myItF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aW = myItF.Value();
|
||||
if (aW.ShapeType() != TopAbs_WIRE)
|
||||
continue;
|
||||
|
||||
myItW.Initialize(aW);
|
||||
for (; myItW.More(); myItW.Next())
|
||||
{
|
||||
const TopoDS_Shape& aE = myItW.Value();
|
||||
if (theMEAvoid.Contains(aE))
|
||||
{
|
||||
if (theFaceToClassify.IsNull())
|
||||
theFaceToClassify = TopoDS::Face(aF);
|
||||
continue;
|
||||
}
|
||||
|
||||
const BOPCol_ListOfShape* pLF = theEFMap.Seek(aE);
|
||||
if (!pLF)
|
||||
continue;
|
||||
BOPCol_ListIteratorOfListOfShape aItLF(*pLF);
|
||||
for (; aItLF.More(); aItLF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aFToAdd = aItLF.Value();
|
||||
if (theMFDone.Add(aFToAdd))
|
||||
theLCB.Append(aFToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vector of solid classifiers
|
||||
typedef BOPCol_NCVector<BOPAlgo_FillIn3DParts> BOPAlgo_VectorOfFillIn3DParts;
|
||||
|
||||
// Functors to perform classification
|
||||
typedef BOPCol_ContextFunctor<BOPAlgo_FillIn3DParts,
|
||||
BOPAlgo_VectorOfFillIn3DParts,
|
||||
Handle(IntTools_Context),
|
||||
IntTools_Context> BOPAlgo_FillIn3DPartsFunctor;
|
||||
|
||||
typedef BOPCol_ContextCnt<BOPAlgo_FillIn3DPartsFunctor,
|
||||
BOPAlgo_VectorOfFillIn3DParts,
|
||||
Handle(IntTools_Context)> BOPAlgo_FillIn3DPartsCnt;
|
||||
|
||||
namespace {
|
||||
static void buildBoxForSolid (const TopoDS_Solid& theSolid,
|
||||
Bnd_Box& theBox)
|
||||
{
|
||||
Standard_Boolean bIsOpenBox = Standard_False;
|
||||
for (TopoDS_Iterator itS (theSolid); itS.More() && !bIsOpenBox; itS.Next())
|
||||
{
|
||||
const TopoDS_Shell& aShell = TopoDS::Shell (itS.Value());
|
||||
bIsOpenBox = BOPTools_AlgoTools::IsOpenShell (aShell);
|
||||
|
||||
if (bIsOpenBox)
|
||||
break;
|
||||
|
||||
for (TopoDS_Iterator itF (aShell); itF.More(); itF.Next())
|
||||
{
|
||||
const TopoDS_Face& aF = TopoDS::Face (itF.Value());
|
||||
|
||||
Bnd_Box aBoxF;
|
||||
BRepBndLib::Add (aF, aBoxF);
|
||||
|
||||
bIsOpenBox = (aBoxF.IsOpenXmin() || aBoxF.IsOpenXmax() ||
|
||||
aBoxF.IsOpenYmin() || aBoxF.IsOpenYmax() ||
|
||||
aBoxF.IsOpenZmin() || aBoxF.IsOpenZmax());
|
||||
|
||||
if (bIsOpenBox)
|
||||
break;
|
||||
|
||||
theBox.Add (aBoxF);
|
||||
}
|
||||
}
|
||||
if (bIsOpenBox || BOPTools_AlgoTools::IsInvertedSolid (theSolid))
|
||||
theBox.SetWhole();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ClassifyFaces
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_Tools::ClassifyFaces(const BOPCol_ListOfShape& theFaces,
|
||||
const BOPCol_ListOfShape& theSolids,
|
||||
const Standard_Boolean theRunParallel,
|
||||
Handle(IntTools_Context)& theContext,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theInParts,
|
||||
const BOPCol_IndexedDataMapOfShapeBox* theBoxes,
|
||||
const BOPCol_DataMapOfShapeListOfShape* theSolidsIF)
|
||||
{
|
||||
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
|
||||
// Fill the vector of shape box with faces and its bounding boxes
|
||||
BOPAlgo_VectorOfShapeBox aVSB(256, anAlloc);
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItLF(theFaces);
|
||||
for (; aItLF.More(); aItLF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aF = aItLF.Value();
|
||||
// Append face to the vector of shape box
|
||||
BOPAlgo_ShapeBox& aSB = aVSB.Append1();
|
||||
aSB.SetShape(aF);
|
||||
|
||||
Bnd_Box aBox;
|
||||
if (theBoxes)
|
||||
{
|
||||
const Bnd_Box* pBox = theBoxes->Seek (aF);
|
||||
if (pBox)
|
||||
aBox = *pBox;
|
||||
}
|
||||
|
||||
if (aBox.IsVoid())
|
||||
{
|
||||
// Build the bounding box
|
||||
BRepBndLib::Add(aF, aBox);
|
||||
}
|
||||
aSB.SetBox(aBox);
|
||||
}
|
||||
|
||||
// Prepare UB tree of bounding boxes of the faces to classify
|
||||
// taking the bounding boxes from the just prepared vector
|
||||
BOPCol_BoxBndTree aBBTree;
|
||||
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
|
||||
|
||||
Standard_Integer aNbF = aVSB.Length();
|
||||
for (Standard_Integer i = 0; i < aNbF; ++i)
|
||||
{
|
||||
aTreeFiller.Add(i, aVSB(i).Box());
|
||||
}
|
||||
|
||||
// Shake tree filler
|
||||
aTreeFiller.Fill();
|
||||
|
||||
// Prepare vector of solids to classify
|
||||
BOPAlgo_VectorOfFillIn3DParts aVFIP;
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItLS(theSolids);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Solid& aSolid = TopoDS::Solid(aItLS.Value());
|
||||
|
||||
// Build the bounding box for the solid
|
||||
Bnd_Box aBox;
|
||||
if (theBoxes)
|
||||
{
|
||||
const Bnd_Box* pBox = theBoxes->Seek (aSolid);
|
||||
if (pBox)
|
||||
aBox = *pBox;
|
||||
}
|
||||
if (aBox.IsVoid())
|
||||
{
|
||||
buildBoxForSolid (aSolid, aBox);
|
||||
}
|
||||
|
||||
// Append solid to the vector
|
||||
BOPAlgo_FillIn3DParts& aFIP = aVFIP.Append1();
|
||||
aFIP.SetSolid(aSolid);
|
||||
aFIP.SetBoxS(aBox);
|
||||
|
||||
if (theSolidsIF)
|
||||
{
|
||||
const BOPCol_ListOfShape* pLIF = theSolidsIF->Seek(aSolid);
|
||||
if (pLIF)
|
||||
aFIP.SetOwnIF(*pLIF);
|
||||
}
|
||||
|
||||
aFIP.SetBBTree(aBBTree);
|
||||
aFIP.SetShapeBoxVector(aVSB);
|
||||
}
|
||||
|
||||
// Perform classification
|
||||
//================================================================
|
||||
BOPAlgo_FillIn3DPartsCnt::Perform(theRunParallel, aVFIP, theContext);
|
||||
//================================================================
|
||||
|
||||
// Analyze the results and fill the resulting map
|
||||
|
||||
Standard_Integer aNbS = aVFIP.Length();
|
||||
for (Standard_Integer i = 0; i < aNbS; ++i)
|
||||
{
|
||||
BOPAlgo_FillIn3DParts& aFIP = aVFIP(i);
|
||||
const TopoDS_Shape& aS = aFIP.Solid();
|
||||
const BOPCol_ListOfShape& aLFIn = aFIP.InFaces();
|
||||
theInParts.Add(aS, aLFIn);
|
||||
}
|
||||
}
|
||||
|
@@ -21,6 +21,9 @@
|
||||
|
||||
#include <BOPCol_BaseAllocator.hxx>
|
||||
#include <BOPDS_IndexedDataMapOfPaveBlockListOfInteger.hxx>
|
||||
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeBox.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeReal.hxx>
|
||||
#include <BOPCol_ListOfListOfShape.hxx>
|
||||
#include <BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock.hxx>
|
||||
@@ -155,6 +158,27 @@ public:
|
||||
const Standard_Real theFuzzyValue,
|
||||
BOPCol_ListOfListOfShape& theChains);
|
||||
|
||||
//! Classifies the faces <theFaces> relatively solids <theSolids>.
|
||||
//! The IN faces for solids are stored into output data map <theInParts>.
|
||||
//!
|
||||
//! The map <theSolidsIF> contains INTERNAL faces of the solids, to avoid
|
||||
//! their additional classification.
|
||||
//!
|
||||
//! Firstly, it checks the intersection of bounding boxes of the shapes.
|
||||
//! If the Box is not stored in the <theShapeBoxMap> map, it builds the box.
|
||||
//! If the bounding boxes of solid and face are interfering the classification is performed.
|
||||
//!
|
||||
//! It is assumed that all faces and solids are already intersected and
|
||||
//! do not have any geometrically coinciding parts without topological
|
||||
//! sharing of these parts
|
||||
Standard_EXPORT static void ClassifyFaces(const BOPCol_ListOfShape& theFaces,
|
||||
const BOPCol_ListOfShape& theSolids,
|
||||
const Standard_Boolean theRunParallel,
|
||||
Handle(IntTools_Context)& theContext,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theInParts,
|
||||
const BOPCol_IndexedDataMapOfShapeBox* theBoxes = 0,
|
||||
const BOPCol_DataMapOfShapeListOfShape* theSolidsIF = 0);
|
||||
|
||||
};
|
||||
|
||||
#endif // _BOPAlgo_Tools_HeaderFile
|
||||
|
@@ -994,46 +994,61 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
|
||||
Handle(IntTools_Context)& theContext,
|
||||
const Standard_Real theFuzz)
|
||||
{
|
||||
Standard_Boolean bFlag;
|
||||
Standard_Integer iErr;
|
||||
Standard_Real aTolF1, aTolF2, aTol;
|
||||
gp_Pnt2d aP2D;
|
||||
gp_Pnt aP;
|
||||
TopoDS_Face aF1, aF2;
|
||||
TopoDS_Edge aE1;
|
||||
TopExp_Explorer aExp;
|
||||
Standard_Real aFuzz1 = (theFuzz > Precision::Confusion() ? theFuzz : Precision::Confusion());
|
||||
//
|
||||
bFlag=Standard_False;
|
||||
//
|
||||
aF1=theF1;
|
||||
aF1.Orientation(TopAbs_FORWARD);
|
||||
aF2=theF2;
|
||||
aF2.Orientation(TopAbs_FORWARD);
|
||||
//
|
||||
aTolF1=BRep_Tool::Tolerance(aF1);
|
||||
// 1
|
||||
aExp.Init(aF1, TopAbs_EDGE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
aE1=(*(TopoDS_Edge*)(&aExp.Current()));
|
||||
if (!BRep_Tool::Degenerated(aE1)) {
|
||||
Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
|
||||
if (aTolE > aTolF1) {
|
||||
aTolF1 = aTolE;
|
||||
Standard_Boolean bFacesSD = Standard_False;
|
||||
|
||||
// The idea is to find a point inside the first face
|
||||
// and check its validity for the second face.
|
||||
// If valid - the faces are same domain.
|
||||
|
||||
gp_Pnt aP1;
|
||||
gp_Pnt2d aP2D1;
|
||||
// Find point inside the first face
|
||||
Standard_Integer iErr =
|
||||
BOPTools_AlgoTools3D::PointInFace(theF1, aP1, aP2D1, theContext);
|
||||
|
||||
if (iErr != 0)
|
||||
{
|
||||
// unable to find the point
|
||||
return bFacesSD;
|
||||
}
|
||||
|
||||
// Check validity of the point for second face
|
||||
|
||||
// Compute the tolerance to check the validity -
|
||||
// sum of tolerance of faces and fuzzy tolerance
|
||||
|
||||
// Compute the tolerance of the faces, taking into account the deviation
|
||||
// of the edges from the surfaces
|
||||
Standard_Real aTolF1 = BRep_Tool::Tolerance(theF1),
|
||||
aTolF2 = BRep_Tool::Tolerance(theF2);
|
||||
|
||||
// Find maximal tolerance of edges.
|
||||
// The faces should have the same boundaries, thus
|
||||
// it does not matter which face to explore.
|
||||
{
|
||||
Standard_Real aTolEMax = -1.;
|
||||
TopExp_Explorer anExpE(theF1, TopAbs_EDGE);
|
||||
for (; anExpE.More(); anExpE.Next())
|
||||
{
|
||||
const TopoDS_Edge& aE = TopoDS::Edge(anExpE.Current());
|
||||
if (!BRep_Tool::Degenerated(aE))
|
||||
{
|
||||
Standard_Real aTolE = BRep_Tool::Tolerance(aE);
|
||||
if (aTolE > aTolEMax)
|
||||
aTolEMax = aTolE;
|
||||
}
|
||||
}
|
||||
if (aTolEMax > aTolF1) aTolF1 = aTolEMax;
|
||||
if (aTolEMax > aTolF2) aTolF2 = aTolEMax;
|
||||
}
|
||||
// 2
|
||||
aTolF2=BRep_Tool::Tolerance(aF2);
|
||||
aTol = aTolF1 + aTolF2 + aFuzz1;
|
||||
//
|
||||
iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
|
||||
theContext);
|
||||
if (!iErr) {
|
||||
bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
|
||||
}
|
||||
//
|
||||
return bFlag;
|
||||
|
||||
// Checking criteria
|
||||
Standard_Real aTol = aTolF1 + aTolF2 + Max(theFuzz, Precision::Confusion());
|
||||
|
||||
// Project and classify the point on second face
|
||||
bFacesSD = theContext->IsValidPointForFace(aP1, theF2, aTol);
|
||||
|
||||
return bFacesSD;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -144,13 +144,6 @@ BRepAdaptor_CompCurve::BRepAdaptor_CompCurve(const TopoDS_Wire& theWire,
|
||||
|
||||
TFirst = 0;
|
||||
TLast = myKnots->Value(myKnots->Length());
|
||||
myPeriod = TLast - TFirst;
|
||||
if (NbEdge == 1) {
|
||||
Periodic = myCurves->Value(1).IsPeriodic();
|
||||
}
|
||||
else {
|
||||
Periodic = Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
void BRepAdaptor_CompCurve::Initialize(const TopoDS_Wire& W,
|
||||
@@ -200,15 +193,6 @@ BRepAdaptor_CompCurve::BRepAdaptor_CompCurve(const TopoDS_Wire& theWire,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BRepAdaptor_CompCurve::SetPeriodic(const Standard_Boolean isPeriodic)
|
||||
{
|
||||
if (myWire.Closed()) {
|
||||
Periodic = isPeriodic;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const TopoDS_Wire& BRepAdaptor_CompCurve::Wire() const
|
||||
{
|
||||
return myWire;
|
||||
@@ -308,13 +292,13 @@ const TopoDS_Wire& BRepAdaptor_CompCurve::Wire() const
|
||||
|
||||
Standard_Boolean BRepAdaptor_CompCurve::IsPeriodic() const
|
||||
{
|
||||
return Periodic;
|
||||
return Standard_False;
|
||||
|
||||
}
|
||||
|
||||
Standard_Real BRepAdaptor_CompCurve::Period() const
|
||||
{
|
||||
return myPeriod;
|
||||
return (TLast - TFirst);
|
||||
}
|
||||
|
||||
gp_Pnt BRepAdaptor_CompCurve::Value(const Standard_Real U) const
|
||||
@@ -475,12 +459,6 @@ const TopoDS_Wire& BRepAdaptor_CompCurve::Wire() const
|
||||
|
||||
|
||||
Wtest = W+Eps; //Offset to discriminate the nodes
|
||||
if(Periodic){
|
||||
Wtest = ElCLib::InPeriod(Wtest,
|
||||
0,
|
||||
myPeriod);
|
||||
W = Wtest-Eps;
|
||||
}
|
||||
|
||||
// Find the index
|
||||
Standard_Boolean Trouve = Standard_False;
|
||||
|
@@ -52,7 +52,13 @@ class Geom_BSplineCurve;
|
||||
//! The Curve from BRepAdaptor allows to use a Wire
|
||||
//! of the BRep topology like a 3D curve.
|
||||
//! Warning: With this class of curve, C0 and C1 continuities
|
||||
//! are not assumed. So be carful with some algorithm!
|
||||
//! are not assumed. So be careful with some algorithm!
|
||||
//! Please note that BRepAdaptor_CompCurve cannot be
|
||||
//! periodic curve at all (even if it contains single
|
||||
//! periodic edge).
|
||||
//!
|
||||
//! BRepAdaptor_CompCurve can only work on valid wires where all edges are
|
||||
//! connected to each other to make a chain.
|
||||
class BRepAdaptor_CompCurve : public Adaptor3d_Curve
|
||||
{
|
||||
public:
|
||||
@@ -75,10 +81,6 @@ public:
|
||||
//! Sets wire <W> and trimmed parameter.
|
||||
Standard_EXPORT void Initialize (const TopoDS_Wire& W, const Standard_Boolean KnotByCurvilinearAbcissa, const Standard_Real First, const Standard_Real Last, const Standard_Real Tol);
|
||||
|
||||
//! Set the flag Periodic.
|
||||
//! Warning: This method has no effect if the wire is not closed
|
||||
Standard_EXPORT void SetPeriodic (const Standard_Boolean Periodic);
|
||||
|
||||
//! Returns the wire.
|
||||
Standard_EXPORT const TopoDS_Wire& Wire() const;
|
||||
|
||||
|
@@ -115,8 +115,9 @@ void BRepBndLib::Add(const TopoDS_Shape& S, Bnd_Box& B, Standard_Boolean useTria
|
||||
}
|
||||
else {
|
||||
for (;ex2.More();ex2.Next()) {
|
||||
BC.Initialize(TopoDS::Edge(ex2.Current()));
|
||||
BndLib_Add3dCurve::Add(BC, BRep_Tool::Tolerance(F), B);
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge(ex2.Current());
|
||||
BC.Initialize(anEdge);
|
||||
BndLib_Add3dCurve::Add(BC, BRep_Tool::Tolerance(anEdge), B);
|
||||
}
|
||||
B.Enlarge(BRep_Tool::Tolerance(F));
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
||||
|
||||
static const Standard_Real Probing_Start = 0.123;
|
||||
static const Standard_Real Probing_End = 0.7;
|
||||
@@ -41,10 +42,11 @@ BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
|
||||
myFace(F),
|
||||
myCurEdgeInd(1),
|
||||
myCurEdgePar(Probing_Start)
|
||||
{
|
||||
{
|
||||
myFace.Orientation(TopAbs_FORWARD);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : CheckPoint
|
||||
//purpose :
|
||||
@@ -71,14 +73,14 @@ Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint)
|
||||
Standard_Real aDistance = aCenterPnt.Distance(thePoint);
|
||||
if (Precision::IsInfinite(aDistance))
|
||||
{
|
||||
thePoint.SetCoord(anUMin - ( anUMax - anUMin ),
|
||||
aVMin - ( aVMax - aVMin ));
|
||||
thePoint.SetCoord (anUMin - (anUMax - anUMin ),
|
||||
aVMin - (aVMax - aVMin ));
|
||||
return Standard_False;
|
||||
}
|
||||
else
|
||||
{
|
||||
Standard_Real anEpsilon = Epsilon(aDistance);
|
||||
if (anEpsilon > Max(anUMax - anUMin, aVMax - aVMin))
|
||||
if (anEpsilon > Max (anUMax - anUMin, aVMax - aVMin))
|
||||
{
|
||||
gp_Vec2d aLinVec(aCenterPnt, thePoint);
|
||||
gp_Dir2d aLinDir(aLinVec);
|
||||
@@ -124,7 +126,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
gp_Lin2d& L,
|
||||
Standard_Real& Par)
|
||||
{
|
||||
TopExp_Explorer anExpF(myFace,TopAbs_EDGE);
|
||||
TopExp_Explorer anExpF(myFace, TopAbs_EDGE);
|
||||
Standard_Integer i;
|
||||
Standard_Real aFPar;
|
||||
Standard_Real aLPar;
|
||||
@@ -151,13 +153,15 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
if (Precision::IsPositiveInfinite(aLPar)) {
|
||||
aFPar = -1.;
|
||||
aLPar = 1.;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
aFPar = aLPar - 1.;
|
||||
}
|
||||
} else if (Precision::IsPositiveInfinite(aLPar))
|
||||
}
|
||||
else if (Precision::IsPositiveInfinite(aLPar))
|
||||
aLPar = aFPar + 1.;
|
||||
|
||||
for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) {
|
||||
for (; myCurEdgePar < Probing_End; myCurEdgePar += Probing_Step) {
|
||||
aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
|
||||
|
||||
gp_Vec2d aTanVec;
|
||||
@@ -174,8 +178,10 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
aTanVec /= Sqrt(aTanMod);
|
||||
Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY());
|
||||
const Standard_Real SmallAngle = 0.001;
|
||||
Standard_Boolean isSmallAngle = Standard_False;
|
||||
if (Abs(aSinA) < SmallAngle)
|
||||
{
|
||||
isSmallAngle = Standard_True;
|
||||
// The line from the input point P to the current point on edge
|
||||
// is tangent to the edge curve. This condition is bad for classification.
|
||||
// Therefore try to go to another point in the hope that there will be
|
||||
@@ -189,13 +195,47 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
|
||||
// Check if ends of a curve lie on a line.
|
||||
aC2d->D0(aFPar, aPOnC);
|
||||
|
||||
Standard_Real aFDist = P.SquareDistance(aPOnC);
|
||||
if (L.SquareDistance(aPOnC) > aTolParConf2) {
|
||||
aC2d->D0(aLPar, aPOnC);
|
||||
|
||||
if (L.SquareDistance(aPOnC) > aTolParConf2) {
|
||||
myCurEdgePar += Probing_Step;
|
||||
Standard_Real aLDist = P.SquareDistance(aPOnC);
|
||||
|
||||
if (isSmallAngle)
|
||||
{
|
||||
//Try to find minimal distance between curve and line
|
||||
|
||||
Geom2dAPI_ProjectPointOnCurve aProj;
|
||||
aProj.Init(P, aC2d, aFPar, aLPar);
|
||||
if (aProj.NbPoints() > 0)
|
||||
{
|
||||
Standard_Real aMinDist = aProj.LowerDistance();
|
||||
aMinDist *= aMinDist;
|
||||
Standard_Real aTMin = aProj.LowerDistanceParameter();
|
||||
if (aMinDist > aFDist)
|
||||
{
|
||||
aMinDist = aFDist;
|
||||
aTMin = aFPar;
|
||||
}
|
||||
if (aMinDist > aLDist)
|
||||
{
|
||||
aMinDist = aLDist;
|
||||
aTMin = aLPar;
|
||||
}
|
||||
if (aMinDist < Par)
|
||||
{
|
||||
Par = aMinDist;
|
||||
if (Par < aTolParConf2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
aC2d->D1(aTMin, aPOnC, aTanVec);
|
||||
aLinDir.SetXY(aTanVec.XY());
|
||||
L = gp_Lin2d(P, aLinDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
myCurEdgePar += Probing_Step;
|
||||
if (myCurEdgePar >= Probing_End) {
|
||||
myCurEdgeInd++;
|
||||
myCurEdgePar = Probing_Start;
|
||||
@@ -217,7 +257,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
|
||||
|
||||
// nothing found, return an horizontal line
|
||||
Par = RealLast();
|
||||
L = gp_Lin2d(P,gp_Dir2d(1,0));
|
||||
L = gp_Lin2d(P, gp_Dir2d(1, 0));
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
@@ -135,10 +135,10 @@ void BRepClass_Intersector::Perform(const gp_Lin2d& L,
|
||||
IntRes2d_Domain DL;
|
||||
//
|
||||
if(P!=RealLast()) {
|
||||
DL.SetValues(L.Location(),0.,aTolZ,ElCLib::Value(P,L),P,aTolZ);
|
||||
DL.SetValues(L.Location(),0.,Precision::PConfusion(),ElCLib::Value(P,L),P,Precision::PConfusion());
|
||||
}
|
||||
else {
|
||||
DL.SetValues(L.Location(),0.,aTolZ,Standard_True);
|
||||
DL.SetValues(L.Location(),0.,Precision::PConfusion(),Standard_True);
|
||||
}
|
||||
|
||||
IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);
|
||||
|
@@ -385,10 +385,8 @@ BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
|
||||
if (Affich)
|
||||
DBRep::Set("theguide", TheGuide);
|
||||
#endif
|
||||
// transform the guide in a single curve (periodic if posssible)
|
||||
Handle(BRepAdaptor_HCompCurve) Guide =
|
||||
new (BRepAdaptor_HCompCurve) (TheGuide);
|
||||
Guide->ChangeCurve().SetPeriodic(Standard_True);
|
||||
// transform the guide in a single curve
|
||||
Handle(BRepAdaptor_HCompCurve) Guide = new (BRepAdaptor_HCompCurve) (TheGuide);
|
||||
|
||||
if (CurvilinearEquivalence) { // trihedron by curvilinear reduced abscissa
|
||||
if (KeepContact == BRepFill_Contact ||
|
||||
|
@@ -131,10 +131,10 @@ BRepLib_MakeWire::BRepLib_MakeWire(const TopoDS_Wire& W,
|
||||
|
||||
void BRepLib_MakeWire::Add(const TopoDS_Wire& W)
|
||||
{
|
||||
TopExp_Explorer ex(W,TopAbs_EDGE);
|
||||
while (ex.More()) {
|
||||
Add(TopoDS::Edge(ex.Current()));
|
||||
ex.Next();
|
||||
for (TopoDS_Iterator it(W); it.More(); it.Next()) {
|
||||
Add(TopoDS::Edge(it.Value()));
|
||||
if (myError != BRepLib_WireDone)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <BRepLib_WireError.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_DataMapOfShapeShape.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <BRepLib_MakeShape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
@@ -175,10 +176,10 @@ private:
|
||||
NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL);
|
||||
|
||||
void CreateNewVertices(const NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL,
|
||||
NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex>& theO2NV);
|
||||
TopTools_DataMapOfShapeShape& theO2NV);
|
||||
|
||||
void CreateNewListOfEdges(const TopTools_ListOfShape& theL,
|
||||
const NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex>& theO2NV,
|
||||
const TopTools_DataMapOfShapeShape& theO2NV,
|
||||
TopTools_ListOfShape& theNewEList);
|
||||
|
||||
void Add(const TopoDS_Edge& E, Standard_Boolean IsCheckGeometryProximity);
|
||||
|
@@ -58,7 +58,7 @@ void BRepLib_MakeWire::Add(const TopTools_ListOfShape& L)
|
||||
|
||||
CollectCoincidentVertices(L, aGrVL);
|
||||
|
||||
NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex> anO2NV;
|
||||
TopTools_DataMapOfShapeShape anO2NV;
|
||||
|
||||
CreateNewVertices(aGrVL, anO2NV);
|
||||
|
||||
@@ -155,8 +155,10 @@ Standard_Boolean BRepLib_MakeWire::BRepLib_BndBoxVertexSelector::
|
||||
Standard_Real aTolV = BRep_Tool::Tolerance(aV);
|
||||
|
||||
Standard_Real aL = myP.SquareDistance(aVPnt);
|
||||
Standard_Real aTol = aTolV + mySTol;
|
||||
aTol *= aTol;
|
||||
|
||||
if (aL < Max(aTolV*aTolV, mySTol))
|
||||
if (aL <= aTol)
|
||||
{
|
||||
myResultInd.Append(theObj);
|
||||
return Standard_True;
|
||||
@@ -176,7 +178,7 @@ void BRepLib_MakeWire::BRepLib_BndBoxVertexSelector::
|
||||
myP = theP;
|
||||
myVBox.Add(myP);
|
||||
myVBox.Enlarge(theTol);
|
||||
mySTol = theTol*theTol;
|
||||
mySTol = theTol;
|
||||
myVInd = theVInd;
|
||||
}
|
||||
|
||||
@@ -188,17 +190,13 @@ void BRepLib_MakeWire::CollectCoincidentVertices(const TopTools_ListOfShape& the
|
||||
NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL)
|
||||
{
|
||||
TopTools_IndexedMapOfShape anAllV;
|
||||
TopTools_ListIteratorOfListOfShape anItL;
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMV2EL;
|
||||
|
||||
TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMV2EL);
|
||||
TopExp_Explorer exp;
|
||||
for (anItL.Initialize(theL); anItL.More(); anItL.Next())
|
||||
TopExp::MapShapesAndAncestors(anItL.Value(), TopAbs_VERTEX, TopAbs_EDGE, aMV2EL);
|
||||
TopExp::MapShapes(myShape, TopAbs_VERTEX, anAllV);
|
||||
|
||||
for (int i = 1; i <= aMV2EL.Extent(); i++)
|
||||
if (aMV2EL(i).Extent() == 1)
|
||||
anAllV.Add(aMV2EL.FindKey(i));
|
||||
TopTools_ListIteratorOfListOfShape anItL(theL);
|
||||
for (; anItL.More(); anItL.Next())
|
||||
TopExp::MapShapes(anItL.Value(), TopAbs_VERTEX, anAllV);
|
||||
|
||||
//aV2CV : vertex <-> its coincident vertices
|
||||
NCollection_DataMap<TopoDS_Vertex, NCollection_Map<TopoDS_Vertex>> aV2CV;
|
||||
@@ -304,7 +302,7 @@ void BRepLib_MakeWire::CollectCoincidentVertices(const TopTools_ListOfShape& the
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepLib_MakeWire::CreateNewVertices(const NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL,
|
||||
NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex>& theO2NV)
|
||||
TopTools_DataMapOfShapeShape& theO2NV)
|
||||
{
|
||||
//map [old vertex => new vertex]
|
||||
//note that already existing shape (i.e. the original ones)
|
||||
@@ -356,7 +354,7 @@ void BRepLib_MakeWire::CreateNewVertices(const NCollection_List<NCollection_List
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepLib_MakeWire::CreateNewListOfEdges(const TopTools_ListOfShape& theL,
|
||||
const NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex>& theO2NV,
|
||||
const TopTools_DataMapOfShapeShape& theO2NV,
|
||||
TopTools_ListOfShape& theNewEList)
|
||||
{
|
||||
///create the new list (theNewEList) from the input list L
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <BRepMesh_Vertex.hxx>
|
||||
#include <BRepMesh_Triangle.hxx>
|
||||
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -304,6 +305,17 @@ void BRepMesh_Delaun::compute(BRepMesh::Array1OfInteger& theVertexIndexes)
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIndex,
|
||||
BRepMesh::MapOfIntegerInteger& thePoly)
|
||||
{
|
||||
createTriangles (theVertexIndex, thePoly, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : createTriangles
|
||||
//purpose : Creates the triangles beetween the node and the polyline.
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIndex,
|
||||
BRepMesh::MapOfIntegerInteger& thePoly,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
BRepMesh::ListOfInteger aLoopEdges, anExternalEdges;
|
||||
const gp_XY& aVertexCoord = myMeshData->GetNode( theVertexIndex ).Coord();
|
||||
@@ -311,6 +323,10 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn
|
||||
BRepMesh::MapOfIntegerInteger::Iterator anEdges( thePoly );
|
||||
for ( ; anEdges.More(); anEdges.Next() )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Standard_Integer anEdgeId = anEdges.Key();
|
||||
const BRepMesh_Edge& anEdge = GetEdge( anEdgeId );
|
||||
|
||||
@@ -408,6 +424,10 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn
|
||||
|
||||
while ( !aLoopEdges.IsEmpty() )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
const BRepMesh_Edge& anEdge = GetEdge( Abs( aLoopEdges.First() ) );
|
||||
if ( anEdge.Movability() != BRepMesh_Deleted )
|
||||
{
|
||||
@@ -425,6 +445,17 @@ void BRepMesh_Delaun::createTriangles(const Standard_Integer theVertexIn
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
BRepMesh::Array1OfInteger& theVertexIndexes)
|
||||
{
|
||||
createTrianglesOnNewVertices (theVertexIndexes, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : createTrianglesOnNewVertices
|
||||
//purpose : Creation of triangles from the new nodes
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
BRepMesh::Array1OfInteger& theVertexIndexes,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
Handle(NCollection_IncAllocator) aAllocator =
|
||||
new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
|
||||
@@ -440,6 +471,11 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
Standard_Integer anUpper = theVertexIndexes.Upper();
|
||||
for( ; anIndex <= anUpper; ++anIndex )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
aAllocator->Reset(Standard_False);
|
||||
BRepMesh::MapOfIntegerInteger aLoopEdges(10, aAllocator);
|
||||
|
||||
@@ -483,6 +519,11 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
isModify = Standard_True;
|
||||
while ( isModify && !aCirclesList.IsEmpty() )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
isModify = Standard_False;
|
||||
BRepMesh::ListOfInteger::Iterator aCircleIt1( aCirclesList );
|
||||
for ( ; aCircleIt1.More(); aCircleIt1.Next() )
|
||||
@@ -503,13 +544,25 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
}
|
||||
}
|
||||
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Creation of triangles with the current node and free edges
|
||||
// and removal of these edges from the list of free edges
|
||||
createTriangles( aVertexIdx, aLoopEdges );
|
||||
createTriangles( aVertexIdx, aLoopEdges, theProgressEntry );
|
||||
}
|
||||
}
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
insertInternalEdges();
|
||||
insertInternalEdges (theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Adjustment of meshes to boundary edges
|
||||
frontierAdjust();
|
||||
@@ -520,6 +573,15 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::insertInternalEdges()
|
||||
{
|
||||
insertInternalEdges (NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : insertInternalEdges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::insertInternalEdges (Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
BRepMesh::HMapOfInteger anInternalEdges = InternalEdges();
|
||||
|
||||
@@ -530,6 +592,11 @@ void BRepMesh_Delaun::insertInternalEdges()
|
||||
BRepMesh::MapOfInteger::Iterator anInernalEdgesIt( *anInternalEdges );
|
||||
for ( ; anInernalEdgesIt.More(); anInernalEdgesIt.Next() )
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const Standard_Integer aLinkIndex = anInernalEdgesIt.Key();
|
||||
const BRepMesh_PairOfIndex& aPair = myMeshData->ElementsConnectedTo(aLinkIndex);
|
||||
|
||||
@@ -2094,12 +2161,21 @@ void BRepMesh_Delaun::RemoveVertex( const BRepMesh_Vertex& theVertex )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : AddVertices
|
||||
//purpose : Adds some vertices in the triangulation.
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices)
|
||||
{
|
||||
AddVertices (theVertices, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddVertices
|
||||
//purpose : Adds some vertices in the triangulation.
|
||||
//=======================================================================
|
||||
void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
std::make_heap(theVertices.begin(), theVertices.end(), ComparatorOfVertexOfDelaun());
|
||||
std::sort_heap(theVertices.begin(), theVertices.end(), ComparatorOfVertexOfDelaun());
|
||||
@@ -2111,7 +2187,7 @@ void BRepMesh_Delaun::AddVertices(BRepMesh::Array1OfVertexOfDelaun& theVertices)
|
||||
for ( Standard_Integer i = aLower; i <= anUpper; ++i )
|
||||
aVertexIndexes(i) = myMeshData->AddNode( theVertices(i) );
|
||||
|
||||
createTrianglesOnNewVertices( aVertexIndexes );
|
||||
createTrianglesOnNewVertices( aVertexIndexes, theProgressEntry );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -33,6 +33,7 @@
|
||||
class Bnd_B2d;
|
||||
class Bnd_Box2d;
|
||||
class BRepMesh_Vertex;
|
||||
class Message_ProgressSentry;
|
||||
|
||||
//! Compute the Delaunay's triangulation with the algorithm of Watson.
|
||||
class BRepMesh_Delaun
|
||||
@@ -61,6 +62,10 @@ public:
|
||||
//! Adds some vertices into the triangulation.
|
||||
Standard_EXPORT void AddVertices (BRepMesh::Array1OfVertexOfDelaun& theVertices);
|
||||
|
||||
//! Adds some vertices into the triangulation.
|
||||
Standard_EXPORT void AddVertices (BRepMesh::Array1OfVertexOfDelaun& theVertices,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Modify mesh to use the edge.
|
||||
//! @return True if done
|
||||
Standard_EXPORT Standard_Boolean UseEdge (const Standard_Integer theEdge);
|
||||
@@ -222,6 +227,10 @@ private:
|
||||
void createTriangles (const Standard_Integer theVertexIndex,
|
||||
BRepMesh::MapOfIntegerInteger& thePoly);
|
||||
|
||||
void createTriangles (const Standard_Integer theVertexIndex,
|
||||
BRepMesh::MapOfIntegerInteger& thePoly,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Add a triangle based on the given oriented edges into mesh
|
||||
void addTriangle (const Standard_Integer (&theEdgesId)[3],
|
||||
const Standard_Boolean (&theEdgesOri)[3],
|
||||
@@ -252,6 +261,10 @@ private:
|
||||
BRepMesh::SequenceOfInteger& thePolygon,
|
||||
BRepMesh::SequenceOfBndB2d& thePolyBoxes);
|
||||
|
||||
//! Creates the triangles on new nodes.
|
||||
void createTrianglesOnNewVertices (BRepMesh::Array1OfInteger& theVertexIndices,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Creates the triangles on new nodes.
|
||||
void createTrianglesOnNewVertices (BRepMesh::Array1OfInteger& theVertexIndices);
|
||||
|
||||
@@ -323,6 +336,9 @@ private:
|
||||
//! Performs insertion of internal edges into mesh.
|
||||
void insertInternalEdges();
|
||||
|
||||
//! Performs insertion of internal edges into mesh.
|
||||
void insertInternalEdges (Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
private:
|
||||
|
||||
Handle(BRepMesh_DataStructureOfDelaun) myMeshData;
|
||||
|
@@ -68,6 +68,7 @@
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
#include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
|
||||
#include <BRep_PointRepresentation.hxx>
|
||||
|
||||
@@ -123,15 +124,25 @@ void BRepMesh_FastDiscret::Perform(const TopoDS_Shape& theShape)
|
||||
OSD_Parallel::ForEach(aFaces.begin(), aFaces.end(), *this, !myParameters.InParallel);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Process
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
|
||||
{
|
||||
Process (theFace, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Process
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscret::Process (const TopoDS_Face& theFace,
|
||||
Message_ProgressSentry* theProgrEntry) const
|
||||
{
|
||||
Handle(BRepMesh_FaceAttribute) anAttribute;
|
||||
if (GetFaceAttribute(theFace, anAttribute))
|
||||
if (GetFaceAttribute(theFace, anAttribute)
|
||||
&& (theProgrEntry == NULL || theProgrEntry->More()))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -139,7 +150,7 @@ void BRepMesh_FastDiscret::Process(const TopoDS_Face& theFace) const
|
||||
|
||||
BRepMesh_FastDiscretFace aTool(myParameters.Angle, myParameters.MinSize,
|
||||
myParameters.InternalVerticesMode, myParameters.ControlSurfaceDeflection);
|
||||
aTool.Perform(anAttribute);
|
||||
aTool.Perform (anAttribute, theProgrEntry);
|
||||
}
|
||||
catch (Standard_Failure)
|
||||
{
|
||||
|
@@ -46,6 +46,7 @@ class BRepMesh_Edge;
|
||||
class BRepMesh_Vertex;
|
||||
class gp_Pnt;
|
||||
class BRepMesh_FaceAttribute;
|
||||
class Message_ProgressSentry;
|
||||
|
||||
//! Algorithm to mesh a shape with respect of the <br>
|
||||
//! frontier the deflection and by option the shared <br>
|
||||
@@ -129,6 +130,12 @@ public:
|
||||
//! parallel threads.
|
||||
Standard_EXPORT void Process(const TopoDS_Face& face) const;
|
||||
|
||||
//! Triangulate a face previously recorded for
|
||||
//! processing by call to Add(). Can be executed in
|
||||
//! parallel threads.
|
||||
Standard_EXPORT void Process (const TopoDS_Face& theFace,
|
||||
Message_ProgressSentry* theProgrEntry) const;
|
||||
|
||||
void operator () (const TopoDS_Face& face) const
|
||||
{
|
||||
Process(face);
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopExp.hxx>
|
||||
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <Bnd_Box2d.hxx>
|
||||
|
||||
@@ -187,7 +188,21 @@ BRepMesh_FastDiscretFace::BRepMesh_FastDiscretFace(
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscretFace::Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute)
|
||||
{
|
||||
add(theAttribute);
|
||||
Perform (theAttribute, NULL);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscretFace::Perform (const Handle(BRepMesh_FaceAttribute)& theAttribute,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
add(theAttribute, theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
commitSurfaceTriangulation();
|
||||
}
|
||||
|
||||
@@ -345,7 +360,8 @@ void BRepMesh_FastDiscretFace::addLinkToMesh(
|
||||
//function : Add
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttribute)
|
||||
void BRepMesh_FastDiscretFace::add (const Handle(BRepMesh_FaceAttribute)& theAttribute,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
if (!theAttribute->IsValid() || theAttribute->ChangeMeshNodes()->IsEmpty())
|
||||
return;
|
||||
@@ -397,12 +413,22 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr
|
||||
(vmax - vmin) < Precision::PConfusion());
|
||||
|
||||
Standard_Real aDef = -1;
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isaline && myStructure->ElementsOfDomain().Extent() > 0 )
|
||||
{
|
||||
if (!rajout)
|
||||
{
|
||||
// compute maximal deflection
|
||||
aDef = control(trigu, Standard_True);
|
||||
aDef = control(trigu, Standard_True, theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rajout = (aDef > myAttribute->GetDefFace() || aDef < 0.);
|
||||
}
|
||||
if (thetype != GeomAbs_Plane)
|
||||
@@ -415,11 +441,21 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr
|
||||
|
||||
if (rajout)
|
||||
{
|
||||
insertInternalVertices(trigu);
|
||||
insertInternalVertices(trigu, theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//control internal points
|
||||
if (myIsControlSurfaceDeflection)
|
||||
aDef = control(trigu, Standard_False);
|
||||
{
|
||||
aDef = control(trigu, Standard_False, theProgressEntry);
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -447,7 +483,8 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr
|
||||
//=======================================================================
|
||||
Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh(
|
||||
const BRepMesh::ListOfVertex& theVertices,
|
||||
BRepMesh_Delaun& theMeshBuilder)
|
||||
BRepMesh_Delaun& theMeshBuilder,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
if (theVertices.IsEmpty())
|
||||
return Standard_False;
|
||||
@@ -457,8 +494,8 @@ Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh(
|
||||
for (Standard_Integer aVertexId = 0; aVertexIt.More(); aVertexIt.Next())
|
||||
aArrayOfNewVertices(++aVertexId) = aVertexIt.Value();
|
||||
|
||||
theMeshBuilder.AddVertices(aArrayOfNewVertices);
|
||||
return Standard_True;
|
||||
theMeshBuilder.AddVertices(aArrayOfNewVertices, theProgressEntry);
|
||||
return theProgressEntry == NULL || theProgressEntry->More();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -527,7 +564,8 @@ static void filterParameters(const BRepMesh::IMapOfReal& theParams,
|
||||
//function : insertInternalVertices
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_FastDiscretFace::insertInternalVertices(BRepMesh_Delaun& theMeshBuilder)
|
||||
void BRepMesh_FastDiscretFace::insertInternalVertices (BRepMesh_Delaun& theMeshBuilder,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator;
|
||||
BRepMesh::ListOfVertex aNewVertices(anAlloc);
|
||||
@@ -555,7 +593,7 @@ void BRepMesh_FastDiscretFace::insertInternalVertices(BRepMesh_Delaun& theMeshBu
|
||||
break;
|
||||
}
|
||||
|
||||
addVerticesToMesh(aNewVertices, theMeshBuilder);
|
||||
addVerticesToMesh(aNewVertices, theMeshBuilder, theProgressEntry);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1182,7 +1220,8 @@ Standard_Boolean BRepMesh_FastDiscretFace::checkDeflectionAndInsert(
|
||||
//=======================================================================
|
||||
Standard_Real BRepMesh_FastDiscretFace::control(
|
||||
BRepMesh_Delaun& theTrigu,
|
||||
const Standard_Boolean theIsFirst)
|
||||
const Standard_Boolean theIsFirst,
|
||||
Message_ProgressSentry* theProgressEntry)
|
||||
{
|
||||
Standard_Integer aTrianglesNb = myStructure->ElementsOfDomain().Extent();
|
||||
if (aTrianglesNb < 1)
|
||||
@@ -1219,6 +1258,11 @@ Standard_Real BRepMesh_FastDiscretFace::control(
|
||||
new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE);
|
||||
for (; aPass <= aPassesNb && aInsertedNb && !isAllDegenerated; ++aPass)
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
aTempAlloc->Reset(Standard_False);
|
||||
BRepMesh::ListOfVertex aNewVertices(aTempAlloc);
|
||||
|
||||
@@ -1236,6 +1280,11 @@ Standard_Real BRepMesh_FastDiscretFace::control(
|
||||
BRepMesh::MapOfInteger::Iterator aTriangleIt(aTriangles);
|
||||
for (; aTriangleIt.More(); aTriangleIt.Next())
|
||||
{
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Standard_Integer aTriangleId = aTriangleIt.Key();
|
||||
const BRepMesh_Triangle& aCurrentTriangle = myStructure->GetElement(aTriangleId);
|
||||
|
||||
@@ -1398,8 +1447,12 @@ Standard_Real BRepMesh_FastDiscretFace::control(
|
||||
<< aP.X() << " " << aP.Y() << " " << aP.Z() << endl;
|
||||
}
|
||||
#endif
|
||||
if (theProgressEntry != NULL && !theProgressEntry->More())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (addVerticesToMesh(aNewVertices, theTrigu))
|
||||
if (addVerticesToMesh(aNewVertices, theTrigu, theProgressEntry))
|
||||
++aInsertedNb;
|
||||
}
|
||||
|
||||
|
@@ -41,6 +41,7 @@ class gp_Pnt2d;
|
||||
class BRepMesh_Edge;
|
||||
class BRepMesh_Vertex;
|
||||
class gp_Pnt;
|
||||
class Message_ProgressSentry;
|
||||
|
||||
//! Algorithm to mesh a face with respect of the frontier
|
||||
//! the deflection and by option the shared components.
|
||||
@@ -62,15 +63,19 @@ public:
|
||||
|
||||
Standard_EXPORT void Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute);
|
||||
|
||||
Standard_EXPORT void Perform (const Handle(BRepMesh_FaceAttribute)& theAttribute,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace,Standard_Transient)
|
||||
|
||||
private:
|
||||
|
||||
void add(const Handle(BRepMesh_FaceAttribute)& theAttribute);
|
||||
void add(const Handle(BRepMesh_FaceAttribute)& theAttribute, Message_ProgressSentry* theProgressEntry);
|
||||
void add(const TopoDS_Vertex& theVertex);
|
||||
|
||||
Standard_Real control(BRepMesh_Delaun& theMeshBuilder,
|
||||
const Standard_Boolean theIsFirst);
|
||||
const Standard_Boolean theIsFirst,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Registers the given nodes in mesh data structure and
|
||||
//! performs refinement of existing mesh.
|
||||
@@ -80,12 +85,14 @@ private:
|
||||
//! @return TRUE if vertices were been inserted, FALSE elewhere.
|
||||
Standard_Boolean addVerticesToMesh(
|
||||
const BRepMesh::ListOfVertex& theVertices,
|
||||
BRepMesh_Delaun& theMeshBuilder);
|
||||
BRepMesh_Delaun& theMeshBuilder,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Calculates nodes lying on face's surface and inserts them to a mesh.
|
||||
//! @param theMeshBuilder initialized tool refining mesh
|
||||
//! in respect to inserting nodes.
|
||||
void insertInternalVertices(BRepMesh_Delaun& theMeshBuilder);
|
||||
void insertInternalVertices(BRepMesh_Delaun& theMeshBuilder,
|
||||
Message_ProgressSentry* theProgressEntry);
|
||||
|
||||
//! Calculates nodes lying on spherical surface.
|
||||
//! @param theNewVertices list of vertices to be extended and added to mesh.
|
||||
|
@@ -54,6 +54,8 @@
|
||||
|
||||
#include <GCPnts_TangentialDeflection.hxx>
|
||||
|
||||
#include <Message_ProgressSentry.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh,BRepMesh_DiscretRoot)
|
||||
|
||||
namespace
|
||||
@@ -63,6 +65,51 @@ namespace
|
||||
static Standard_Boolean IS_IN_PARALLEL = Standard_False;
|
||||
}
|
||||
|
||||
class BRepMesh_IncrementalMesh::FaceListFunctor
|
||||
{
|
||||
public:
|
||||
FaceListFunctor (BRepMesh_IncrementalMesh* theAlgo,
|
||||
const Handle(Message_ProgressIndicator)& theProgress,
|
||||
Standard_Boolean theParallel)
|
||||
: myAlgo (theAlgo),
|
||||
mySentry (theProgress, "Mesh faces", 0, theAlgo->myFaces.Size(), 1),
|
||||
myThreadId (OSD_Thread::Current()),
|
||||
myIsParallel (theParallel),
|
||||
myHasProgress (!theProgress.IsNull())
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (const Standard_Integer theFaceIndex) const
|
||||
{
|
||||
if (!mySentry.More())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TopoDS_Face& aFace = myAlgo->myFaces.ChangeValue (theFaceIndex);
|
||||
myAlgo->myMesh->Process (aFace, &mySentry);
|
||||
|
||||
if (myIsParallel)
|
||||
{
|
||||
// use a trick to avoid mutex locks - increment the progress only within main thread
|
||||
if (myHasProgress && myThreadId == OSD_Thread::Current())
|
||||
{
|
||||
mySentry.Next (OSD_Parallel::NbLogicalProcessors());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mySentry.Next();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
mutable BRepMesh_IncrementalMesh* myAlgo;
|
||||
mutable Message_ProgressSentry mySentry;
|
||||
Standard_ThreadId myThreadId;
|
||||
Standard_Boolean myIsParallel;
|
||||
Standard_Boolean myHasProgress;
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : Default constructor
|
||||
@@ -202,24 +249,44 @@ void BRepMesh_IncrementalMesh::collectFaces()
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_IncrementalMesh::Perform()
|
||||
{
|
||||
Perform (Handle(Message_ProgressIndicator)());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_IncrementalMesh::Perform (const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
init();
|
||||
|
||||
if (myMesh.IsNull())
|
||||
return;
|
||||
|
||||
update();
|
||||
update (theProgress);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : update()
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_IncrementalMesh::update()
|
||||
void BRepMesh_IncrementalMesh::update (const Handle(Message_ProgressIndicator)& theProgress)
|
||||
{
|
||||
Message_ProgressSentry anOuterSentry (theProgress, "Updating", 0, 100, 1);
|
||||
|
||||
// Update edges data
|
||||
TopExp_Explorer aExplorer(myShape, TopAbs_EDGE);
|
||||
for (; aExplorer.More(); aExplorer.Next())
|
||||
anOuterSentry.Next(9);
|
||||
{
|
||||
int aNbEdges = 0;
|
||||
for (TopExp_Explorer aExplorer (myShape, TopAbs_EDGE); aExplorer.More(); aExplorer.Next())
|
||||
{
|
||||
++aNbEdges;
|
||||
}
|
||||
|
||||
Message_ProgressSentry anEdgeSentry (theProgress, "Update edges data", 0, aNbEdges, 1);
|
||||
for (TopExp_Explorer aExplorer (myShape, TopAbs_EDGE);
|
||||
aExplorer.More() && anEdgeSentry.More(); aExplorer.Next(), anEdgeSentry.Next())
|
||||
{
|
||||
const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
|
||||
if(!BRep_Tool::IsGeometric(aEdge))
|
||||
@@ -227,16 +294,49 @@ void BRepMesh_IncrementalMesh::update()
|
||||
|
||||
update(aEdge);
|
||||
}
|
||||
}
|
||||
|
||||
if (!anOuterSentry.More())
|
||||
{
|
||||
myStatus = BRepMesh_UserBreak;
|
||||
return;
|
||||
}
|
||||
anOuterSentry.Next(5);
|
||||
|
||||
// Update faces data
|
||||
NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
|
||||
for (; aFaceIt.More(); aFaceIt.Next())
|
||||
for (Message_ProgressSentry aFacesSentry (theProgress, "Update faces data", 0, myFaces.Size(), 1);
|
||||
aFaceIt.More() && aFacesSentry.More(); aFaceIt.Next(), aFacesSentry.Next())
|
||||
{
|
||||
update(aFaceIt.Value());
|
||||
}
|
||||
|
||||
if (!anOuterSentry.More())
|
||||
{
|
||||
myStatus = BRepMesh_UserBreak;
|
||||
return;
|
||||
}
|
||||
|
||||
anOuterSentry.Next(80);
|
||||
|
||||
{
|
||||
// Mesh faces
|
||||
OSD_Parallel::ForEach(myFaces.begin(), myFaces.end(), *myMesh, !myParameters.InParallel);
|
||||
FaceListFunctor aFacesFunctor (this, theProgress, myParameters.InParallel);
|
||||
OSD_Parallel::For (0, myFaces.Size(), aFacesFunctor, !myParameters.InParallel);
|
||||
}
|
||||
|
||||
commit();
|
||||
if (!anOuterSentry.More())
|
||||
{
|
||||
myStatus = BRepMesh_UserBreak;
|
||||
return;
|
||||
}
|
||||
|
||||
anOuterSentry.Next(5);
|
||||
{
|
||||
Message_ProgressSentry aSentry (theProgress, "Commit", 0, myFaces.Size(), 1);
|
||||
commit (aSentry);
|
||||
}
|
||||
anOuterSentry.Next();
|
||||
clear();
|
||||
}
|
||||
|
||||
@@ -493,10 +593,10 @@ void BRepMesh_IncrementalMesh::update(const TopoDS_Face& theFace)
|
||||
//function : commit
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepMesh_IncrementalMesh::commit()
|
||||
void BRepMesh_IncrementalMesh::commit (Message_ProgressSentry& theSentry)
|
||||
{
|
||||
NCollection_Vector<TopoDS_Face>::Iterator aFaceIt(myFaces);
|
||||
for (; aFaceIt.More(); aFaceIt.Next())
|
||||
for (; aFaceIt.More() && theSentry.More(); aFaceIt.Next(), theSentry.Next())
|
||||
commitEdges(aFaceIt.Value());
|
||||
|
||||
discretizeFreeEdges();
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Message_ProgressIndicator;
|
||||
class Poly_Triangulation;
|
||||
class TopoDS_Shape;
|
||||
class TopoDS_Edge;
|
||||
@@ -69,6 +70,9 @@ public: //! @name mesher API
|
||||
//! Performs meshing ot the shape.
|
||||
Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
|
||||
|
||||
//! Performs meshing ot the shape.
|
||||
Standard_EXPORT void Perform(const Handle(Message_ProgressIndicator)& theProgress);
|
||||
|
||||
public: //! @name accessing to parameters.
|
||||
|
||||
//! Returns meshing parameters
|
||||
@@ -126,7 +130,7 @@ protected:
|
||||
private:
|
||||
|
||||
//! Builds the incremental mesh for the shape.
|
||||
void update();
|
||||
void update(const Handle(Message_ProgressIndicator)& theProgress);
|
||||
|
||||
//! Checks triangulation of the given face for consistency
|
||||
//! with the chosen tolerance. If some edge of face has no
|
||||
@@ -167,7 +171,7 @@ private:
|
||||
const Standard_Boolean isWithCheck);
|
||||
|
||||
//! Stores mesh to the shape.
|
||||
void commit();
|
||||
void commit(Message_ProgressSentry& theSentry);
|
||||
|
||||
//! Stores mesh of internal edges to the face.
|
||||
void commitEdges(const TopoDS_Face& theFace);
|
||||
@@ -175,6 +179,9 @@ private:
|
||||
//! Clears internal data structures.
|
||||
void clear();
|
||||
|
||||
private:
|
||||
class FaceListFunctor;
|
||||
|
||||
protected:
|
||||
|
||||
BRepMesh::DMapOfEdgeListOfTriangulationBool myEdges;
|
||||
|
@@ -23,7 +23,8 @@ enum BRepMesh_Status
|
||||
BRepMesh_OpenWire = 0x1,
|
||||
BRepMesh_SelfIntersectingWire = 0x2,
|
||||
BRepMesh_Failure = 0x4,
|
||||
BRepMesh_ReMesh = 0x8
|
||||
BRepMesh_ReMesh = 0x8,
|
||||
BRepMesh_UserBreak = 0x16
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -1146,23 +1146,23 @@ proc _run_test {scriptsdir group gridname casefile echo} {
|
||||
# execute test scripts
|
||||
if { [file exists $scriptsdir/$group/begin] } {
|
||||
puts "Executing $scriptsdir/$group/begin..."; flush stdout
|
||||
uplevel source $scriptsdir/$group/begin
|
||||
uplevel source -encoding utf-8 $scriptsdir/$group/begin
|
||||
}
|
||||
if { [file exists $scriptsdir/$group/$gridname/begin] } {
|
||||
puts "Executing $scriptsdir/$group/$gridname/begin..."; flush stdout
|
||||
uplevel source $scriptsdir/$group/$gridname/begin
|
||||
uplevel source -encoding utf-8 $scriptsdir/$group/$gridname/begin
|
||||
}
|
||||
|
||||
puts "Executing $casefile..."; flush stdout
|
||||
uplevel source $casefile
|
||||
uplevel source -encoding utf-8 $casefile
|
||||
|
||||
if { [file exists $scriptsdir/$group/$gridname/end] } {
|
||||
puts "Executing $scriptsdir/$group/$gridname/end..."; flush stdout
|
||||
uplevel source $scriptsdir/$group/$gridname/end
|
||||
uplevel source -encoding utf-8 $scriptsdir/$group/$gridname/end
|
||||
}
|
||||
if { [file exists $scriptsdir/$group/end] } {
|
||||
puts "Executing $scriptsdir/$group/end..."; flush stdout
|
||||
uplevel source $scriptsdir/$group/end
|
||||
uplevel source -encoding utf-8 $scriptsdir/$group/end
|
||||
}
|
||||
} res] {
|
||||
puts "Tcl Exception: $res"
|
||||
|
@@ -130,7 +130,7 @@ Standard_Boolean Expr_NamedUnknown::IsLinear () const
|
||||
Handle(Expr_GeneralExpression) Expr_NamedUnknown::Derivative (const Handle(Expr_NamedUnknown)& X) const
|
||||
{
|
||||
Handle(Expr_NamedUnknown) me = this;
|
||||
if (me != X) {
|
||||
if (!me->IsIdentical(X)) {
|
||||
if (IsAssigned()) {
|
||||
return myExpression->Derivative(X);
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Adaptor2d_Curve2d.hxx>
|
||||
#include <Extrema_Curve2dTool.hxx>
|
||||
#include <Extrema_ExtPC2d.hxx>
|
||||
#include <Extrema_POnCurv2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
@@ -43,6 +44,7 @@
|
||||
#define Pnt_hxx <gp_Pnt2d.hxx>
|
||||
#define Vec gp_Vec2d
|
||||
#define Vec_hxx <gp_Vec2d.hxx>
|
||||
#define Extrema_GExtPC Extrema_ExtPC2d
|
||||
#define Extrema_GenExtCC Extrema_ECC2d
|
||||
#define Extrema_GenExtCC_hxx <Extrema_ECC2d.hxx>
|
||||
#include <Extrema_GenExtCC.gxx>
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Adaptor3d_Curve.hxx>
|
||||
#include <Extrema_CurveTool.hxx>
|
||||
#include <Extrema_ExtPC.hxx>
|
||||
#include <Extrema_POnCurv.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
@@ -43,6 +44,7 @@
|
||||
#define Pnt_hxx <gp_Pnt.hxx>
|
||||
#define Vec gp_Vec
|
||||
#define Vec_hxx <gp_Vec.hxx>
|
||||
#define Extrema_GExtPC Extrema_ExtPC
|
||||
#define Extrema_GenExtCC Extrema_ECC
|
||||
#define Extrema_GenExtCC_hxx <Extrema_ECC.hxx>
|
||||
#include <Extrema_GenExtCC.gxx>
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <StdFail_NotDone.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_ListOfInteger.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
#include <NCollection_CellFilter.hxx>
|
||||
@@ -92,6 +93,29 @@ private:
|
||||
Standard_Boolean myIsFind;
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : ProjPOnC
|
||||
//purpose : Projects the point on the curve and returns the minimal
|
||||
// projection distance
|
||||
//=======================================================================
|
||||
static Standard_Real ProjPOnC(const Pnt& theP,
|
||||
Extrema_GExtPC& theProjTool)
|
||||
{
|
||||
Standard_Real aDist = ::RealLast();
|
||||
theProjTool.Perform(theP);
|
||||
if (theProjTool.IsDone() && theProjTool.NbExt())
|
||||
{
|
||||
for (Standard_Integer i = 1; i <= theProjTool.NbExt(); ++i)
|
||||
{
|
||||
Standard_Real aD = theProjTool.SquareDistance(i);
|
||||
if (aD < aDist)
|
||||
aDist = aD;
|
||||
}
|
||||
aDist = sqrt(aDist);
|
||||
}
|
||||
return aDist;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Extrema_GenExtCC
|
||||
//purpose :
|
||||
@@ -262,9 +286,10 @@ void Extrema_GenExtCC::Perform()
|
||||
aFinder.SetFunctionalMinimalValue(0.0); // Best distance cannot be lower than 0.0.
|
||||
|
||||
// Size computed to have cell index inside of int32 value.
|
||||
const Standard_Real aCellSize = Max(anIntervals1.Last() - anIntervals1.First(),
|
||||
const Standard_Real aCellSize = Max(Max(anIntervals1.Last() - anIntervals1.First(),
|
||||
anIntervals2.Last() - anIntervals2.First())
|
||||
* Precision::PConfusion() / (2.0 * Sqrt(2.0));
|
||||
* Precision::PConfusion() / (2.0 * Sqrt(2.0)),
|
||||
Precision::PConfusion());
|
||||
Extrema_CCPointsInspector anInspector(aCellSize);
|
||||
NCollection_CellFilter<Extrema_CCPointsInspector> aFilter(aCellSize);
|
||||
NCollection_Vector<gp_XY> aPnts;
|
||||
@@ -329,28 +354,55 @@ void Extrema_GenExtCC::Perform()
|
||||
}
|
||||
}
|
||||
|
||||
if (aPnts.Size() == 0)
|
||||
const Standard_Integer aNbSol = aPnts.Length();
|
||||
if (aNbSol == 0)
|
||||
{
|
||||
// No solutions.
|
||||
myDone = Standard_False;
|
||||
return;
|
||||
}
|
||||
|
||||
myDone = Standard_True;
|
||||
|
||||
if (aNbSol == 1)
|
||||
{
|
||||
// Single solution
|
||||
const gp_XY& aSol = aPnts.First();
|
||||
myPoints1.Append(aSol.X());
|
||||
myPoints2.Append(aSol.Y());
|
||||
return;
|
||||
}
|
||||
|
||||
// More than one solution is found.
|
||||
// Check for infinity solutions case, for this:
|
||||
// Sort points lexicographically and check midpoint between each two neighboring points.
|
||||
// If all midpoints functional value is acceptable
|
||||
// then set myParallel flag to true and return one solution.
|
||||
// If all midpoints functional value is acceptable then check the projection distances
|
||||
// of the bounding points of the curves onto the opposite curves.
|
||||
// If these distances are also acceptable set myParallel flag to true and return one solution.
|
||||
std::sort(aPnts.begin(), aPnts.end(), comp);
|
||||
Standard_Boolean isParallel = Standard_False;
|
||||
Standard_Real aVal = 0.0;
|
||||
math_Vector aVec(1,2, 0.0);
|
||||
|
||||
// Avoid mark parallel case when have duplicates out of tolerance.
|
||||
// Bad conditioned task: bug25635_1, bug23706_10, bug23706_13.
|
||||
if (aPnts.Size() >= 2)
|
||||
{
|
||||
isParallel = Standard_True;
|
||||
for(Standard_Integer anIdx = aPnts.Lower(); anIdx <= aPnts.Upper() - 1; anIdx++)
|
||||
// Solutions to pass into result.
|
||||
// If the parallel segment is found, save only extreme solutions on that segment.
|
||||
// The first and last solutions will always be the extreme ones, thus save them unconditionally.
|
||||
TColStd_ListOfInteger aSolutions;
|
||||
|
||||
// Manages the addition of the solution into result.
|
||||
// Set it to TRUE to add the first solution.
|
||||
Standard_Boolean bSaveSolution = Standard_True;
|
||||
|
||||
// Define direction of the second curve relatively the first one
|
||||
// (it will be needed for projection).
|
||||
Standard_Boolean bDirsCoinside = Standard_True;
|
||||
// Check also if the found solutions are not concentrated in one point
|
||||
// on any of the curves. And if they are, avoid marking the curves as parallel.
|
||||
Standard_Boolean bDifferentSolutions = Standard_False;
|
||||
|
||||
Standard_Boolean isParallel = Standard_True;
|
||||
Standard_Real aVal = 0.0;
|
||||
math_Vector aVec(1, 2, 0.0);
|
||||
|
||||
// Iterate on all solutions and collect the extreme solutions on all parallel segments.
|
||||
for (Standard_Integer anIdx = 0; anIdx < aNbSol - 1; anIdx++)
|
||||
{
|
||||
const gp_XY& aCurrent = aPnts(anIdx);
|
||||
const gp_XY& aNext = aPnts(anIdx + 1);
|
||||
@@ -360,32 +412,92 @@ void Extrema_GenExtCC::Perform()
|
||||
|
||||
aFunc.Value(aVec, aVal);
|
||||
|
||||
if (Abs(aVal - aF) > Precision::Confusion())
|
||||
if (Abs(aVal - aF) < Precision::Confusion())
|
||||
{
|
||||
isParallel = Standard_False;
|
||||
break;
|
||||
// It seems the parallel segment is found.
|
||||
// Save only extreme solutions on that segment.
|
||||
if (bSaveSolution)
|
||||
{
|
||||
// Add current solution as the beginning of the parallel segment.
|
||||
aSolutions.Append(anIdx);
|
||||
// Do not keep the next solution in current parallel segment.
|
||||
bSaveSolution = Standard_False;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mid point does not satisfy the tolerance criteria, curves are not parallel.
|
||||
isParallel = Standard_False;
|
||||
// Add current solution as the last one in previous parallel segment.
|
||||
aSolutions.Append(anIdx);
|
||||
// Save also the next solution as the first one in next parallel segment.
|
||||
bSaveSolution = Standard_True;
|
||||
}
|
||||
|
||||
if (!bDifferentSolutions)
|
||||
{
|
||||
if (aNext.X() > aCurrent.X())
|
||||
{
|
||||
if (aNext.Y() > aCurrent.Y())
|
||||
{
|
||||
bDifferentSolutions = Standard_True;
|
||||
bDirsCoinside = Standard_True;
|
||||
}
|
||||
else if (aNext.Y() < aCurrent.Y())
|
||||
{
|
||||
bDifferentSolutions = Standard_True;
|
||||
bDirsCoinside = Standard_False;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Save the last solution
|
||||
aSolutions.Append(aNbSol - 1);
|
||||
|
||||
if (!bDifferentSolutions)
|
||||
isParallel = Standard_False;
|
||||
|
||||
if (isParallel)
|
||||
{
|
||||
// For the check on parallel case it is also necessary to check additionally
|
||||
// if the ends of the curves do not diverge. For this, project the bounding
|
||||
// points of the curves on the opposite curves and check the distances.
|
||||
|
||||
Standard_Real aT1[2] = {myLowBorder(1), myUppBorder(1)};
|
||||
Standard_Real aT2[2] = {bDirsCoinside ? myLowBorder(2) : myUppBorder(2),
|
||||
bDirsCoinside ? myUppBorder(2) : myLowBorder(2)};
|
||||
|
||||
Extrema_GExtPC anExtPC1, anExtPC2;
|
||||
anExtPC1.Initialize(C1, myLowBorder(1), myUppBorder(1));
|
||||
anExtPC2.Initialize(C2, myLowBorder(2), myUppBorder(2));
|
||||
|
||||
for (Standard_Integer iT = 0; isParallel && (iT < 2); ++iT)
|
||||
{
|
||||
Standard_Real aDist1 = ProjPOnC(C1.Value(aT1[iT]), anExtPC2);
|
||||
Standard_Real aDist2 = ProjPOnC(C2.Value(aT2[iT]), anExtPC1);
|
||||
isParallel = (Abs(Min(aDist1, aDist2) - aF) < Precision::Confusion());
|
||||
}
|
||||
}
|
||||
|
||||
if (isParallel)
|
||||
{
|
||||
const gp_XY& aCurrent = aPnts.First();
|
||||
myPoints1.Append(aCurrent.X());
|
||||
myPoints2.Append(aCurrent.Y());
|
||||
// Keep only one solution
|
||||
const gp_XY& aSol = aPnts.First();
|
||||
myPoints1.Append(aSol.X());
|
||||
myPoints2.Append(aSol.Y());
|
||||
myParallel = Standard_True;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(Standard_Integer anIdx = aPnts.Lower(); anIdx <= aPnts.Upper(); anIdx++)
|
||||
// Keep all saved solutions
|
||||
TColStd_ListIteratorOfListOfInteger aItSol(aSolutions);
|
||||
for (; aItSol.More(); aItSol.Next())
|
||||
{
|
||||
const gp_XY& aCurrent = aPnts(anIdx);
|
||||
myPoints1.Append(aCurrent.X());
|
||||
myPoints2.Append(aCurrent.Y());
|
||||
const gp_XY& aSol = aPnts(aItSol.Value());
|
||||
myPoints1.Append(aSol.X());
|
||||
myPoints2.Append(aSol.Y());
|
||||
}
|
||||
}
|
||||
|
||||
myDone = Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -12,8 +12,10 @@ Font_FTLibrary.hxx
|
||||
Font_NameOfFont.hxx
|
||||
Font_NListOfSystemFont.hxx
|
||||
Font_Rect.hxx
|
||||
Font_StrictLevel.hxx
|
||||
Font_SystemFont.cxx
|
||||
Font_SystemFont.hxx
|
||||
Font_NameOfFont.hxx
|
||||
Font_TextFormatter.hxx
|
||||
Font_TextFormatter.cxx
|
||||
Font_UnicodeSubset.hxx
|
||||
|
@@ -15,10 +15,12 @@
|
||||
#include <Font_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>
|
||||
@@ -34,9 +36,6 @@
|
||||
#include <GeomAdaptor_HSurface.hxx>
|
||||
#include <GeomLib.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <ShapeFix_Edge.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <TColGeom2d_HSequenceOfBoundedCurve.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
@@ -45,6 +44,9 @@
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_DataMapOfShapeInteger.hxx>
|
||||
#include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
@@ -57,6 +59,7 @@ 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)
|
||||
@@ -66,9 +69,50 @@ namespace
|
||||
|
||||
//! Auxiliary method to convert FT_Vector to gp_XY
|
||||
static gp_XY readFTVec (const FT_Vector& theVec,
|
||||
const Standard_Real theScaleUnits)
|
||||
const Standard_Real theScaleUnits,
|
||||
const Standard_Real theWidthScaling = 1.0)
|
||||
{
|
||||
return gp_XY (theScaleUnits * Standard_Real(theVec.x) / 64.0, theScaleUnits * Standard_Real(theVec.y) / 64.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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -97,15 +141,6 @@ void Font_BRepFont::init()
|
||||
myCurve2dAdaptor = new Geom2dAdaptor_HCurve();
|
||||
Handle(Adaptor3d_HSurface) aSurfAdaptor = new GeomAdaptor_HSurface (mySurface);
|
||||
myCurvOnSurf.Load (aSurfAdaptor);
|
||||
|
||||
myFixer.FixWireMode() = 1;
|
||||
myFixer.FixOrientationMode() = 1;
|
||||
myFixer.FixSplitFaceMode() = 1; // some glyphs might be composed from several faces
|
||||
Handle(ShapeFix_Wire) aWireFixer = myFixer.FixWireTool();
|
||||
aWireFixer->FixConnectedMode() = 1;
|
||||
aWireFixer->ClosedWireMode() = Standard_True;
|
||||
Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape();
|
||||
myFixer.SetContext (aContext);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -127,7 +162,7 @@ Font_BRepFont::Font_BRepFont (const NCollection_String& theFontPath,
|
||||
}
|
||||
|
||||
myScaleUnits = getScale (theSize);
|
||||
Font_FTFont::Init (theFontPath, THE_FONT_SIZE, THE_RESOLUTION_DPI);
|
||||
Font_FTFont::Init (theFontPath.ToCString(), THE_FONT_PARAMS);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -136,7 +171,8 @@ Font_BRepFont::Font_BRepFont (const NCollection_String& theFontPath,
|
||||
// =======================================================================
|
||||
Font_BRepFont::Font_BRepFont (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize)
|
||||
const Standard_Real theSize,
|
||||
const Font_StrictLevel theStrictLevel)
|
||||
: myPrecision (Precision::Confusion()),
|
||||
myScaleUnits (1.0),
|
||||
myIsCompositeCurve (Standard_False),
|
||||
@@ -150,7 +186,7 @@ Font_BRepFont::Font_BRepFont (const NCollection_String& theFontName,
|
||||
}
|
||||
|
||||
myScaleUnits = getScale (theSize);
|
||||
Font_FTFont::Init (theFontName, theFontAspect, THE_FONT_SIZE, THE_RESOLUTION_DPI);
|
||||
Font_FTFont::FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -189,16 +225,17 @@ bool Font_BRepFont::Init (const NCollection_String& theFontPath,
|
||||
}
|
||||
|
||||
myScaleUnits = getScale (theSize);
|
||||
return Font_FTFont::Init (theFontPath, THE_FONT_SIZE, THE_RESOLUTION_DPI);
|
||||
return Font_FTFont::Init (theFontPath.ToCString(), THE_FONT_PARAMS);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// function : FindAndInit
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_BRepFont::Init (const NCollection_String& theFontName,
|
||||
bool Font_BRepFont::FindAndInit (const TCollection_AsciiString& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize)
|
||||
const Standard_Real theSize,
|
||||
const Font_StrictLevel theStrictLevel)
|
||||
{
|
||||
if (theSize <= myPrecision * 100.0)
|
||||
{
|
||||
@@ -206,7 +243,7 @@ bool Font_BRepFont::Init (const NCollection_String& theFontName,
|
||||
}
|
||||
|
||||
myScaleUnits = getScale (theSize);
|
||||
return Font_FTFont::Init (theFontName, theFontAspect, THE_FONT_SIZE, THE_RESOLUTION_DPI);
|
||||
return Font_FTFont::FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -240,6 +277,131 @@ bool Font_BRepFont::to3d (const Handle(Geom2d_Curve)& theCurve2d,
|
||||
return !theCurve3d.IsNull();
|
||||
}
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// function : buildFaces
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Font_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);
|
||||
}
|
||||
|
||||
TopoDS_Iterator anExplor (aFaceComp);
|
||||
if (!anExplor.More()) //if (aFaceComp.NbChildren() == 0)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
TopoDS_Shape aSingleShape = anExplor.Value(); anExplor.Next();
|
||||
if (!anExplor.More()) //if (aFaceComp.NbChildren() == 1)
|
||||
{
|
||||
//theRes = TopoDS_Iterator (aFaceComp).Value();
|
||||
theRes = aSingleShape;
|
||||
}
|
||||
else
|
||||
{
|
||||
theRes = aFaceComp;
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// function : renderGlyph
|
||||
// purpose :
|
||||
@@ -249,7 +411,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
{
|
||||
theShape.Nullify();
|
||||
if (!loadGlyph (theChar)
|
||||
|| myFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
|| myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
@@ -258,14 +420,13 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
return !theShape.IsNull();
|
||||
}
|
||||
|
||||
FT_Outline& anOutline = myFTFace->glyph->outline;
|
||||
|
||||
const FT_Outline& anOutline = myActiveFTFace->glyph->outline;
|
||||
if (!anOutline.n_contours)
|
||||
return Standard_False;
|
||||
|
||||
TopLoc_Location aLoc;
|
||||
TopoDS_Face aFaceDraft;
|
||||
myBuilder.MakeFace (aFaceDraft, mySurface, myPrecision);
|
||||
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.
|
||||
@@ -277,7 +438,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
const short anEndIndex = anOutline.contours[aContour];
|
||||
const short aPntsNb = (anEndIndex - aStartIndex) + 1;
|
||||
aStartIndex = anEndIndex + 1;
|
||||
if (aPntsNb < 3)
|
||||
if (aPntsNb < 3 && !myFontParams.IsSingleStrokeFont)
|
||||
{
|
||||
// closed contour can not be constructed from < 3 points
|
||||
continue;
|
||||
@@ -286,10 +447,11 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
BRepBuilderAPI_MakeWire aWireMaker;
|
||||
|
||||
gp_XY aPntPrev;
|
||||
gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits);
|
||||
gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits);
|
||||
gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits, myWidthScaling);
|
||||
gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits, myWidthScaling);
|
||||
|
||||
Standard_Integer aLinePnts = (FT_CURVE_TAG(aTags[aPntsNb - 1]) == FT_Curve_Tag_On) ? 1 : 0;
|
||||
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
|
||||
@@ -298,15 +460,15 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
{
|
||||
aPntPrev = aPntCurr;
|
||||
aPntCurr = aPntNext;
|
||||
aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits);
|
||||
aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits, myWidthScaling);
|
||||
|
||||
// process tags
|
||||
if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_On)
|
||||
{
|
||||
if (aLinePnts < 1)
|
||||
if (!isLineSeg)
|
||||
{
|
||||
aPntLine1 = aPntCurr;
|
||||
aLinePnts = 1;
|
||||
isLineSeg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -315,7 +477,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
if (aLen <= myPrecision)
|
||||
{
|
||||
aPntLine1 = aPntCurr;
|
||||
aLinePnts = 1;
|
||||
isLineSeg = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -339,7 +501,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
}
|
||||
else if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_Conic)
|
||||
{
|
||||
aLinePnts = 0;
|
||||
isLineSeg = false;
|
||||
gp_XY aPntPrev2 = aPntPrev;
|
||||
gp_XY aPntNext2 = aPntNext;
|
||||
|
||||
@@ -378,11 +540,11 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
else if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_Cubic
|
||||
&& FT_CURVE_TAG(aTags[(aPntId + 1) % aPntsNb]) == FT_Curve_Tag_Cubic)
|
||||
{
|
||||
aLinePnts = 0;
|
||||
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)));
|
||||
my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits, myWidthScaling)));
|
||||
Handle(Geom2d_BezierCurve) aBezier = new Geom2d_BezierCurve (my4Poles);
|
||||
if (myIsCompositeCurve)
|
||||
{
|
||||
@@ -411,7 +573,8 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
|
||||
const gp_Pnt2d aFirstPnt = aDraft2d->StartPoint();
|
||||
const gp_Pnt2d aLastPnt = aDraft2d->EndPoint();
|
||||
if (!aFirstPnt.IsEqual (aLastPnt, myPrecision))
|
||||
if (!myFontParams.IsSingleStrokeFont
|
||||
&& !aFirstPnt.IsEqual (aLastPnt, myPrecision))
|
||||
{
|
||||
Handle(Geom2d_TrimmedCurve) aLine = GCE2d_MakeSegment (aLastPnt, aFirstPnt);
|
||||
myConcatMaker.Add (aLine, myPrecision);
|
||||
@@ -438,7 +601,8 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
TopExp::Vertices (aWireMaker.Wire(), aFirstV, aLastV);
|
||||
gp_Pnt aFirstPoint = BRep_Tool::Pnt (aFirstV);
|
||||
gp_Pnt aLastPoint = BRep_Tool::Pnt (aLastV);
|
||||
if (!aFirstPoint.IsEqual (aLastPoint, myPrecision))
|
||||
if (!myFontParams.IsSingleStrokeFont
|
||||
&& !aFirstPoint.IsEqual (aLastPoint, myPrecision))
|
||||
{
|
||||
aWireMaker.Add (BRepLib_MakeEdge (aFirstV, aLastV));
|
||||
}
|
||||
@@ -450,31 +614,38 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar,
|
||||
}
|
||||
|
||||
TopoDS_Wire aWireDraft = aWireMaker.Wire();
|
||||
//if (anOrient == FT_ORIENTATION_FILL_LEFT)
|
||||
//{
|
||||
// According to the TrueType specification, clockwise contours must be filled
|
||||
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();
|
||||
//}
|
||||
myBuilder.Add (aFaceDraft, aWireDraft);
|
||||
}
|
||||
aWires.Append (aWireDraft);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aFaceCompDraft.IsNull())
|
||||
{
|
||||
myBuilder.MakeCompound (aFaceCompDraft);
|
||||
}
|
||||
myBuilder.Add (aFaceCompDraft, aWireDraft);
|
||||
}
|
||||
}
|
||||
|
||||
myFixer.Init (aFaceDraft);
|
||||
myFixer.Perform();
|
||||
theShape = myFixer.Result();
|
||||
if (!theShape.IsNull()
|
||||
&& theShape.ShapeType() != TopAbs_FACE)
|
||||
if (!aWires.IsEmpty())
|
||||
{
|
||||
// shape fix can not fix orientation within the single call
|
||||
TopoDS_Compound aComp;
|
||||
myBuilder.MakeCompound (aComp);
|
||||
for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
|
||||
{
|
||||
TopoDS_Face aFace = TopoDS::Face (aFaceIter.Current());
|
||||
myFixer.Init (aFace);
|
||||
myFixer.Perform();
|
||||
myBuilder.Add (aComp, myFixer.Result());
|
||||
buildFaces (aWires, theShape);
|
||||
}
|
||||
theShape = aComp;
|
||||
else if (!aFaceCompDraft.IsNull())
|
||||
{
|
||||
theShape = aFaceCompDraft;
|
||||
}
|
||||
|
||||
myCache.Bind (theChar, theShape);
|
||||
|
@@ -27,10 +27,12 @@
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_String.hxx>
|
||||
#include <Standard_Mutex.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopTools_SequenceOfShape.hxx>
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Font_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.
|
||||
@@ -41,6 +43,7 @@
|
||||
//! Although caching should eliminate this issue after rendering of sufficient number of glyphs.
|
||||
class Font_BRepFont : protected Font_FTFont
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Font_BRepFont, Font_FTFont)
|
||||
public:
|
||||
|
||||
//! Empty constructor
|
||||
@@ -56,9 +59,11 @@ public:
|
||||
//! @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 Font_BRepFont (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize);
|
||||
const Standard_Real theSize,
|
||||
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||
|
||||
//! Release currently loaded font.
|
||||
Standard_EXPORT virtual void Release() Standard_OVERRIDE;
|
||||
@@ -70,7 +75,7 @@ public:
|
||||
Standard_EXPORT bool Init (const NCollection_String& theFontPath,
|
||||
const Standard_Real theSize);
|
||||
|
||||
//! Initialize the font.
|
||||
//! 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:
|
||||
@@ -78,10 +83,12 @@ public:
|
||||
//! @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 Init (const NCollection_String& theFontName,
|
||||
Standard_EXPORT bool FindAndInit (const TCollection_AsciiString& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Real theSize);
|
||||
const Standard_Real theSize,
|
||||
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||
|
||||
//! Render single glyph as TopoDS_Shape.
|
||||
//! @param theChar glyph identifier
|
||||
@@ -96,6 +103,13 @@ public:
|
||||
//! 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.
|
||||
@@ -164,6 +178,17 @@ public:
|
||||
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.
|
||||
@@ -183,6 +208,14 @@ private:
|
||||
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>
|
||||
@@ -201,15 +234,7 @@ protected: //! @name Shared temporary variables for glyph construction
|
||||
TColgp_Array1OfPnt2d my3Poles;
|
||||
TColgp_Array1OfPnt2d my4Poles;
|
||||
BRep_Builder myBuilder;
|
||||
ShapeFix_Face myFixer;
|
||||
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Font_BRepFont,Font_FTFont)
|
||||
|
||||
};
|
||||
|
||||
// Definition of HANDLE object using Standard_DefineHandle.hxx
|
||||
DEFINE_STANDARD_HANDLE(Font_BRepFont, Font_FTFont)
|
||||
|
||||
#endif // _Font_BRepFont_H__
|
||||
|
@@ -18,6 +18,10 @@
|
||||
#include <Font_FTLibrary.hxx>
|
||||
#include <Font_FontMgr.hxx>
|
||||
#include <Font_TextFormatter.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
@@ -31,10 +35,12 @@ IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient)
|
||||
Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
|
||||
: myFTLib (theFTLib),
|
||||
myFTFace (NULL),
|
||||
myPointSize (0U),
|
||||
myActiveFTFace(NULL),
|
||||
myFontAspect (Font_FontAspect_Regular),
|
||||
myWidthScaling(1.0),
|
||||
myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
|
||||
myKernAdvance(new FT_Vector()),
|
||||
myUChar (0U)
|
||||
myUChar (0U),
|
||||
myToUseUnicodeSubsetFallback (Font_FontMgr::ToUseUnicodeSubsetFallback())
|
||||
{
|
||||
if (myFTLib.IsNull())
|
||||
{
|
||||
@@ -49,7 +55,6 @@ Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
|
||||
Font_FTFont::~Font_FTFont()
|
||||
{
|
||||
Release();
|
||||
delete myKernAdvance;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -66,61 +71,173 @@ void Font_FTFont::Release()
|
||||
FT_Done_Face (myFTFace);
|
||||
myFTFace = NULL;
|
||||
}
|
||||
myActiveFTFace = NULL;
|
||||
myBuffer.Nullify();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::Init (const NCollection_String& theFontPath,
|
||||
const unsigned int thePointSize,
|
||||
const unsigned int theResolution)
|
||||
bool Font_FTFont::Init (const Handle(NCollection_Buffer)& theData,
|
||||
const TCollection_AsciiString& theFileName,
|
||||
const Font_FTFontParams& theParams)
|
||||
{
|
||||
Release();
|
||||
myFontPath = theFontPath;
|
||||
myPointSize = thePointSize;
|
||||
myBuffer = theData;
|
||||
myFontPath = theFileName;
|
||||
myFontParams = theParams;
|
||||
if (!myFTLib->IsValid())
|
||||
{
|
||||
//std::cerr << "FreeType library is unavailable!\n";
|
||||
Message::DefaultMessenger()->Send ("FreeType library is unavailable", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!theData.IsNull())
|
||||
{
|
||||
if (FT_New_Memory_Face (myFTLib->Instance(), theData->Data(), (FT_Long )theData->Size(), 0, &myFTFace) != 0)
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' failed to load from memory", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
|
||||
{
|
||||
//std::cerr << "Font '" << myFontPath << "' fail to load!\n";
|
||||
//Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' failed to load from file", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
|
||||
}
|
||||
|
||||
if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
|
||||
{
|
||||
//std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' doesn't contains Unicode charmap", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
|
||||
else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (theParams.PointSize), theParams.Resolution, theParams.Resolution) != 0)
|
||||
{
|
||||
//std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' doesn't contains Unicode charmap of requested size", Message_Trace);
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (theParams.ToSynthesizeItalic)
|
||||
{
|
||||
const double THE_SHEAR_ANGLE = 10.0 * M_PI / 180.0;
|
||||
|
||||
FT_Matrix aMat;
|
||||
aMat.xx = FT_Fixed (Cos (-THE_SHEAR_ANGLE) * (1 << 16));
|
||||
aMat.xy = 0;
|
||||
aMat.yx = 0;
|
||||
aMat.yy = aMat.xx;
|
||||
|
||||
FT_Fixed aFactor = FT_Fixed (Tan (THE_SHEAR_ANGLE) * (1 << 16));
|
||||
aMat.xy += FT_MulFix (aFactor, aMat.xx);
|
||||
|
||||
FT_Set_Transform (myFTFace, &aMat, 0);
|
||||
}
|
||||
myActiveFTFace = myFTFace;
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// function : FindAndCreate
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::Init (const NCollection_String& theFontName,
|
||||
Handle(Font_FTFont) Font_FTFont::FindAndCreate (const TCollection_AsciiString& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const unsigned int thePointSize,
|
||||
const unsigned int theResolution)
|
||||
const Font_FTFontParams& theParams,
|
||||
const Font_StrictLevel theStrictLevel)
|
||||
{
|
||||
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||
const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theFontName.ToCString());
|
||||
Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize);
|
||||
return !aRequestedFont.IsNull()
|
||||
&& Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution);
|
||||
Font_FontAspect aFontAspect = theFontAspect;
|
||||
if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (theFontName, theStrictLevel, aFontAspect))
|
||||
{
|
||||
Font_FTFontParams aParams = theParams;
|
||||
if (aRequestedFont->IsSingleStrokeFont())
|
||||
{
|
||||
aParams.IsSingleStrokeFont = true;
|
||||
}
|
||||
|
||||
const TCollection_AsciiString& aPath = aRequestedFont->FontPathAny (aFontAspect, aParams.ToSynthesizeItalic);
|
||||
Handle(Font_FTFont) aFont = new Font_FTFont();
|
||||
if (aFont->Init (aPath, aParams))
|
||||
{
|
||||
aFont->myFontAspect = aFontAspect;
|
||||
return aFont;
|
||||
}
|
||||
}
|
||||
return Handle(Font_FTFont)();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : FindAndInit
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::FindAndInit (const TCollection_AsciiString& theFontName,
|
||||
Font_FontAspect theFontAspect,
|
||||
const Font_FTFontParams& theParams,
|
||||
Font_StrictLevel theStrictLevel)
|
||||
{
|
||||
Font_FTFontParams aParams = theParams;
|
||||
myFontAspect = theFontAspect;
|
||||
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||
if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (theFontName.ToCString(), theStrictLevel, myFontAspect))
|
||||
{
|
||||
if (aRequestedFont->IsSingleStrokeFont())
|
||||
{
|
||||
aParams.IsSingleStrokeFont = true;
|
||||
}
|
||||
|
||||
const TCollection_AsciiString& aPath = aRequestedFont->FontPathAny (myFontAspect, aParams.ToSynthesizeItalic);
|
||||
return Init (aPath, aParams);
|
||||
}
|
||||
Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : findAndInitFallback
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::findAndInitFallback (Font_UnicodeSubset theSubset)
|
||||
{
|
||||
if (!myFallbackFaces[theSubset].IsNull())
|
||||
{
|
||||
return myFallbackFaces[theSubset]->IsValid();
|
||||
}
|
||||
|
||||
myFallbackFaces[theSubset] = new Font_FTFont (myFTLib);
|
||||
myFallbackFaces[theSubset]->myToUseUnicodeSubsetFallback = false; // no recursion
|
||||
|
||||
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||
if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFallbackFont (theSubset, myFontAspect))
|
||||
{
|
||||
Font_FTFontParams aParams = myFontParams;
|
||||
aParams.IsSingleStrokeFont = aRequestedFont->IsSingleStrokeFont();
|
||||
|
||||
const TCollection_AsciiString& aPath = aRequestedFont->FontPathAny (myFontAspect, aParams.ToSynthesizeItalic);
|
||||
if (myFallbackFaces[theSubset]->Init (aPath, aParams))
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Font_FTFont, using fallback font '") + aRequestedFont->FontName() + "'"
|
||||
+ " for symbols unsupported by '" + myFTFace->family_name + "'", Message_Trace);
|
||||
}
|
||||
}
|
||||
return myFallbackFaces[theSubset]->IsValid();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : HasSymbol
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::HasSymbol (Standard_Utf32Char theUChar) const
|
||||
{
|
||||
return FT_Get_Char_Index (myFTFace, theUChar) != 0;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -131,14 +248,31 @@ bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
|
||||
{
|
||||
if (myUChar == theUChar)
|
||||
{
|
||||
return true;
|
||||
return myUChar != 0;
|
||||
}
|
||||
|
||||
myGlyphImg.Clear();
|
||||
myUChar = 0;
|
||||
if (theUChar == 0
|
||||
|| FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
|
||||
|| myFTFace->glyph == NULL)
|
||||
myActiveFTFace = myFTFace;
|
||||
if (theUChar == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (myToUseUnicodeSubsetFallback
|
||||
&& !HasSymbol (theUChar))
|
||||
{
|
||||
// try using fallback
|
||||
const Font_UnicodeSubset aSubset = CharSubset (theUChar);
|
||||
if (findAndInitFallback (aSubset)
|
||||
&& myFallbackFaces[aSubset]->HasSymbol (theUChar))
|
||||
{
|
||||
myActiveFTFace = myFallbackFaces[aSubset]->myFTFace;
|
||||
}
|
||||
}
|
||||
|
||||
if (FT_Load_Char (myActiveFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
|
||||
|| myActiveFTFace->glyph == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -155,26 +289,68 @@ bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
|
||||
{
|
||||
myGlyphImg.Clear();
|
||||
myUChar = 0;
|
||||
myActiveFTFace = myFTFace;
|
||||
|
||||
if (theUChar != 0
|
||||
&& myToUseUnicodeSubsetFallback
|
||||
&& !HasSymbol (theUChar))
|
||||
{
|
||||
// try using fallback
|
||||
const Font_UnicodeSubset aSubset = CharSubset (theUChar);
|
||||
if (findAndInitFallback (aSubset)
|
||||
&& myFallbackFaces[aSubset]->HasSymbol (theUChar))
|
||||
{
|
||||
myActiveFTFace = myFallbackFaces[aSubset]->myFTFace;
|
||||
}
|
||||
}
|
||||
|
||||
if (theUChar == 0
|
||||
|| FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
|
||||
|| myFTFace->glyph == NULL
|
||||
|| myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
||||
|| FT_Load_Char (myActiveFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
|
||||
|| myActiveFTFace->glyph == NULL
|
||||
|| myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
|
||||
if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
|
||||
|| aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
|
||||
FT_Bitmap aBitmap = myActiveFTFace->glyph->bitmap;
|
||||
if (aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aBitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
|
||||
{
|
||||
if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
|
||||
aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
|
||||
}
|
||||
else if (aBitmap.pixel_mode == FT_PIXEL_MODE_MONO)
|
||||
{
|
||||
if (!myGlyphImg.InitTrash (Image_Format_Gray, aBitmap.width, aBitmap.rows))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
|
||||
const int aNumOfBytesInRow = aBitmap.width / 8 + (aBitmap.width % 8 ? 1 : 0);
|
||||
for (int aRow = 0; aRow < (int )aBitmap.rows; ++aRow)
|
||||
{
|
||||
for (int aCol = 0; aCol < (int )aBitmap.width; ++aCol)
|
||||
{
|
||||
const int aBitOn = aBitmap.buffer[aNumOfBytesInRow * aRow + aCol / 8] & (0x80 >> (aCol % 8));
|
||||
//*myGlyphImg.ChangeRawValue (aRow, aCol) = aBitOn ? 255 : 0;
|
||||
myGlyphImg.ChangeRow (aRow)[aCol] = aBitOn ? 255 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
myUChar = theUChar;
|
||||
return true;
|
||||
}
|
||||
@@ -183,24 +359,58 @@ bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
|
||||
// function : GlyphMaxSizeX
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
unsigned int Font_FTFont::GlyphMaxSizeX() const
|
||||
unsigned int Font_FTFont::GlyphMaxSizeX (bool theToIncludeFallback) const
|
||||
{
|
||||
if (!theToIncludeFallback)
|
||||
{
|
||||
float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
|
||||
? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.max_advance);
|
||||
return (unsigned int)(aWidth + 0.5f);
|
||||
}
|
||||
|
||||
unsigned int aWidth = GlyphMaxSizeX (false);
|
||||
if (theToIncludeFallback)
|
||||
{
|
||||
for (Standard_Integer aFontIter = 0; aFontIter < Font_UnicodeSubset_NB; ++aFontIter)
|
||||
{
|
||||
if (!myFallbackFaces[aFontIter].IsNull()
|
||||
&& myFallbackFaces[aFontIter]->IsValid())
|
||||
{
|
||||
aWidth = std::max (aWidth, myFallbackFaces[aFontIter]->GlyphMaxSizeX (false));
|
||||
}
|
||||
}
|
||||
}
|
||||
return aWidth;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GlyphMaxSizeY
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
unsigned int Font_FTFont::GlyphMaxSizeY() const
|
||||
unsigned int Font_FTFont::GlyphMaxSizeY (bool theToIncludeFallback) const
|
||||
{
|
||||
if (!theToIncludeFallback)
|
||||
{
|
||||
float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
|
||||
? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
|
||||
: fromFTPoints<float> (myFTFace->size->metrics.height);
|
||||
return (unsigned int)(aHeight + 0.5f);
|
||||
}
|
||||
|
||||
unsigned int aHeight = GlyphMaxSizeY (false);
|
||||
if (theToIncludeFallback)
|
||||
{
|
||||
for (Standard_Integer aFontIter = 0; aFontIter < Font_UnicodeSubset_NB; ++aFontIter)
|
||||
{
|
||||
if (!myFallbackFaces[aFontIter].IsNull()
|
||||
&& myFallbackFaces[aFontIter]->IsValid())
|
||||
{
|
||||
aHeight = std::max (aHeight, myFallbackFaces[aFontIter]->GlyphMaxSizeY (false));
|
||||
}
|
||||
}
|
||||
}
|
||||
return aHeight;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -234,8 +444,8 @@ float Font_FTFont::LineSpacing() const
|
||||
// function : AdvanceX
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
|
||||
const Standard_Utf32Char theUCharNext)
|
||||
float Font_FTFont::AdvanceX (Standard_Utf32Char theUChar,
|
||||
Standard_Utf32Char theUCharNext)
|
||||
{
|
||||
loadGlyph (theUChar);
|
||||
return AdvanceX (theUCharNext);
|
||||
@@ -245,71 +455,103 @@ float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
|
||||
// function : AdvanceY
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar,
|
||||
const Standard_Utf32Char theUCharNext)
|
||||
float Font_FTFont::AdvanceY (Standard_Utf32Char theUChar,
|
||||
Standard_Utf32Char theUCharNext)
|
||||
{
|
||||
loadGlyph (theUChar);
|
||||
return AdvanceY (theUCharNext);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : getKerning
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool Font_FTFont::getKerning (FT_Vector& theKern,
|
||||
Standard_Utf32Char theUCharCurr,
|
||||
Standard_Utf32Char theUCharNext) const
|
||||
{
|
||||
theKern.x = 0;
|
||||
theKern.y = 0;
|
||||
if (theUCharNext != 0 && FT_HAS_KERNING(myActiveFTFace) != 0)
|
||||
{
|
||||
const FT_UInt aCharCurr = FT_Get_Char_Index (myActiveFTFace, theUCharCurr);
|
||||
const FT_UInt aCharNext = FT_Get_Char_Index (myActiveFTFace, theUCharNext);
|
||||
if (aCharCurr == 0 || aCharNext == 0
|
||||
|| FT_Get_Kerning (myActiveFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, &theKern) != 0)
|
||||
{
|
||||
theKern.x = 0;
|
||||
theKern.y = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : AdvanceX
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
|
||||
float Font_FTFont::AdvanceX (Standard_Utf32Char theUCharNext) const
|
||||
{
|
||||
if (myUChar == 0)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
|
||||
|| FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
|
||||
{
|
||||
return fromFTPoints<float> (myFTFace->glyph->advance.x);
|
||||
}
|
||||
return fromFTPoints<float> (myKernAdvance->x + myFTFace->glyph->advance.x);
|
||||
FT_Vector aKern;
|
||||
getKerning (aKern, myUChar, theUCharNext);
|
||||
return myWidthScaling * fromFTPoints<float> (myActiveFTFace->glyph->advance.x + aKern.x);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : AdvanceY
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
|
||||
float Font_FTFont::AdvanceY (Standard_Utf32Char theUCharNext) const
|
||||
{
|
||||
if (myUChar == 0)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
|
||||
|| FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
|
||||
{
|
||||
return fromFTPoints<float> (myFTFace->glyph->advance.y);
|
||||
}
|
||||
return fromFTPoints<float> (myKernAdvance->y + myFTFace->glyph->advance.y);
|
||||
FT_Vector aKern;
|
||||
getKerning (aKern, myUChar, theUCharNext);
|
||||
return fromFTPoints<float> (myActiveFTFace->glyph->advance.y + aKern.y);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GlyphsNumber
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Integer Font_FTFont::GlyphsNumber() const
|
||||
Standard_Integer Font_FTFont::GlyphsNumber (bool theToIncludeFallback) const
|
||||
{
|
||||
return myFTFace->num_glyphs;
|
||||
Standard_Integer aNbGlyphs = myFTFace->num_glyphs;
|
||||
if (theToIncludeFallback)
|
||||
{
|
||||
for (Standard_Integer aFontIter = 0; aFontIter < Font_UnicodeSubset_NB; ++aFontIter)
|
||||
{
|
||||
if (!myFallbackFaces[aFontIter].IsNull()
|
||||
&& myFallbackFaces[aFontIter]->IsValid())
|
||||
{
|
||||
aNbGlyphs += myFallbackFaces[aFontIter]->GlyphsNumber (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return aNbGlyphs;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : theRect
|
||||
// function : GlyphRect
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Font_FTFont::GlyphRect (Font_Rect& theRect) const
|
||||
{
|
||||
const FT_Bitmap& aBitmap = myFTFace->glyph->bitmap;
|
||||
theRect.Left = float(myFTFace->glyph->bitmap_left);
|
||||
theRect.Top = float(myFTFace->glyph->bitmap_top);
|
||||
theRect.Right = float(myFTFace->glyph->bitmap_left + (int )aBitmap.width);
|
||||
theRect.Bottom = float(myFTFace->glyph->bitmap_top - (int )aBitmap.rows);
|
||||
const FT_Bitmap& aBitmap = myActiveFTFace->glyph->bitmap;
|
||||
theRect.Left = float(myActiveFTFace->glyph->bitmap_left);
|
||||
theRect.Top = float(myActiveFTFace->glyph->bitmap_top);
|
||||
theRect.Right = float(myActiveFTFace->glyph->bitmap_left + (int )aBitmap.width);
|
||||
theRect.Bottom = float(myActiveFTFace->glyph->bitmap_top - (int )aBitmap.rows);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@@ -18,21 +18,120 @@
|
||||
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Font_Rect.hxx>
|
||||
#include <Font_StrictLevel.hxx>
|
||||
#include <Font_UnicodeSubset.hxx>
|
||||
#include <Graphic3d_HorizontalTextAlignment.hxx>
|
||||
#include <Graphic3d_VerticalTextAlignment.hxx>
|
||||
#include <Image_PixMap.hxx>
|
||||
#include <NCollection_String.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
// forward declarations to avoid including of FreeType headers
|
||||
typedef struct FT_FaceRec_* FT_Face;
|
||||
typedef struct FT_Vector_ FT_Vector;
|
||||
class Font_FTLibrary;
|
||||
|
||||
//! Font initialization parameters.
|
||||
struct Font_FTFontParams
|
||||
{
|
||||
unsigned int PointSize; //!< face size in points (1/72 inch)
|
||||
unsigned int Resolution; //!< resolution of the target device in dpi for FT_Set_Char_Size()
|
||||
bool ToSynthesizeItalic; //!< generate italic style (e.g. for font family having no italic style); FALSE by default
|
||||
bool IsSingleStrokeFont; //!< single-stroke (one-line) font, FALSE by default
|
||||
|
||||
//! Empty constructor.
|
||||
Font_FTFontParams() : PointSize (0), Resolution (72u), ToSynthesizeItalic (false), IsSingleStrokeFont (false) {}
|
||||
|
||||
//! Constructor.
|
||||
Font_FTFontParams (unsigned int thePointSize,
|
||||
unsigned int theResolution)
|
||||
: PointSize (thePointSize), Resolution (theResolution), ToSynthesizeItalic (false), IsSingleStrokeFont (false) {}
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Font_FTFont, Standard_Transient)
|
||||
|
||||
//! Wrapper over FreeType font.
|
||||
//! Notice that this class uses internal buffers for loaded glyphs
|
||||
//! and it is absolutely UNSAFE to load/read glyph from concurrent threads!
|
||||
class Font_FTFont : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Font_FTFont, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Find the font Initialize the font.
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param theParams initialization parameters
|
||||
//! @param theStrictLevel search strict level for using aliases and fallback
|
||||
//! @return true on success
|
||||
Standard_EXPORT static Handle(Font_FTFont) FindAndCreate (const TCollection_AsciiString& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Font_FTFontParams& theParams,
|
||||
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||
|
||||
//! Return TRUE if specified character is within subset of modern CJK characters.
|
||||
static bool IsCharFromCJK (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x03400 && theUChar <= 0x04DFF)
|
||||
|| (theUChar >= 0x04E00 && theUChar <= 0x09FFF)
|
||||
|| (theUChar >= 0x0F900 && theUChar <= 0x0FAFF)
|
||||
|| (theUChar >= 0x20000 && theUChar <= 0x2A6DF)
|
||||
|| (theUChar >= 0x2F800 && theUChar <= 0x2FA1F)
|
||||
// Hiragana and Katakana (Japanese) are NOT part of CJK, but CJK fonts usually include these symbols
|
||||
|| IsCharFromHiragana (theUChar)
|
||||
|| IsCharFromKatakana (theUChar);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character is within subset of Hiragana (Japanese).
|
||||
static bool IsCharFromHiragana (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x03040 && theUChar <= 0x0309F);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character is within subset of Katakana (Japanese).
|
||||
static bool IsCharFromKatakana (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x030A0 && theUChar <= 0x030FF);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character is within subset of modern Korean characters (Hangul).
|
||||
static bool IsCharFromKorean (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x01100 && theUChar <= 0x011FF)
|
||||
|| (theUChar >= 0x03130 && theUChar <= 0x0318F)
|
||||
|| (theUChar >= 0x0AC00 && theUChar <= 0x0D7A3);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character is within subset of Arabic characters.
|
||||
static bool IsCharFromArabic (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return (theUChar >= 0x00600 && theUChar <= 0x006FF);
|
||||
}
|
||||
|
||||
//! Return TRUE if specified character should be displayed in Right-to-Left order.
|
||||
static bool IsCharRightToLeft (Standard_Utf32Char theUChar)
|
||||
{
|
||||
return IsCharFromArabic(theUChar);
|
||||
}
|
||||
|
||||
//! Determine Unicode subset for specified character
|
||||
static Font_UnicodeSubset CharSubset (Standard_Utf32Char theUChar)
|
||||
{
|
||||
if (IsCharFromCJK (theUChar))
|
||||
{
|
||||
return Font_UnicodeSubset_CJK;
|
||||
}
|
||||
else if (IsCharFromKorean (theUChar))
|
||||
{
|
||||
return Font_UnicodeSubset_Korean;
|
||||
}
|
||||
else if (IsCharFromArabic (theUChar))
|
||||
{
|
||||
return Font_UnicodeSubset_Arabic;
|
||||
}
|
||||
return Font_UnicodeSubset_Western;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
//! Create uninitialized instance.
|
||||
@@ -53,25 +152,53 @@ public:
|
||||
return myGlyphImg;
|
||||
}
|
||||
|
||||
//! Initialize the font.
|
||||
//! Initialize the font from the given file path.
|
||||
//! @param theFontPath path to the font
|
||||
//! @param thePointSize the face size in points (1/72 inch)
|
||||
//! @param theResolution the resolution of the target device in dpi
|
||||
//! @param theParams initialization parameters
|
||||
//! @return true on success
|
||||
Standard_EXPORT bool Init (const NCollection_String& theFontPath,
|
||||
const unsigned int thePointSize,
|
||||
const unsigned int theResolution);
|
||||
bool Init (const TCollection_AsciiString& theFontPath,
|
||||
const Font_FTFontParams& theParams)
|
||||
{
|
||||
return Init (Handle(NCollection_Buffer)(), theFontPath, theParams);
|
||||
}
|
||||
|
||||
//! Initialize the font.
|
||||
//! Initialize the font from the given file path or memory buffer.
|
||||
//! @param theData memory to read from, should NOT be freed after initialization!
|
||||
//! when NULL, function will attempt to open theFileName file
|
||||
//! @param theFileName optional path to the font
|
||||
//! @param theParams initialization parameters
|
||||
//! @return true on success
|
||||
Standard_EXPORT bool Init (const Handle(NCollection_Buffer)& theData,
|
||||
const TCollection_AsciiString& theFileName,
|
||||
const Font_FTFontParams& theParams);
|
||||
|
||||
//! Find (using Font_FontMgr) and initialize the font from the given name.
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param thePointSize the face size in points (1/72 inch)
|
||||
//! @param theResolution the resolution of the target device in dpi
|
||||
//! @param theParams initialization parameters
|
||||
//! @param theStrictLevel search strict level for using aliases and fallback
|
||||
//! @return true on success
|
||||
Standard_EXPORT bool Init (const NCollection_String& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const unsigned int thePointSize,
|
||||
const unsigned int theResolution);
|
||||
Standard_EXPORT bool FindAndInit (const TCollection_AsciiString& theFontName,
|
||||
Font_FontAspect theFontAspect,
|
||||
const Font_FTFontParams& theParams,
|
||||
Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
|
||||
|
||||
//! Return flag to use fallback fonts in case if used font does not include symbols from specific Unicode subset; TRUE by default.
|
||||
//! @sa Font_FontMgr::ToUseUnicodeSubsetFallback()
|
||||
Standard_Boolean ToUseUnicodeSubsetFallback() const { return myToUseUnicodeSubsetFallback; }
|
||||
|
||||
//! Set if fallback fonts should be used in case if used font does not include symbols from specific Unicode subset.
|
||||
void SetUseUnicodeSubsetFallback (Standard_Boolean theToFallback) { myToUseUnicodeSubsetFallback = theToFallback; }
|
||||
|
||||
//! Return TRUE if this is single-stroke (one-line) font, FALSE by default.
|
||||
//! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software.
|
||||
bool IsSingleStrokeFont() const { return myFontParams.IsSingleStrokeFont; }
|
||||
|
||||
//! Set if this font should be rendered as single-stroke (one-line).
|
||||
void SetSingleStrokeFont (bool theIsSingleLine) { myFontParams.IsSingleStrokeFont = theIsSingleLine; }
|
||||
|
||||
//! Return TRUE if italic style should be synthesized; FALSE by default.
|
||||
bool ToSynthesizeItalic() const { return myFontParams.ToSynthesizeItalic; }
|
||||
|
||||
//! Release currently loaded font.
|
||||
Standard_EXPORT virtual void Release();
|
||||
@@ -80,10 +207,10 @@ public:
|
||||
Standard_EXPORT bool RenderGlyph (const Standard_Utf32Char theChar);
|
||||
|
||||
//! @return maximal glyph width in pixels (rendered to bitmap).
|
||||
Standard_EXPORT unsigned int GlyphMaxSizeX() const;
|
||||
Standard_EXPORT unsigned int GlyphMaxSizeX (bool theToIncludeFallback = false) const;
|
||||
|
||||
//! @return maximal glyph height in pixels (rendered to bitmap).
|
||||
Standard_EXPORT unsigned int GlyphMaxSizeY() const;
|
||||
Standard_EXPORT unsigned int GlyphMaxSizeY (bool theToIncludeFallback = false) const;
|
||||
|
||||
//! @return vertical distance from the horizontal baseline to the highest character coordinate.
|
||||
Standard_EXPORT float Ascender() const;
|
||||
@@ -97,29 +224,46 @@ public:
|
||||
//! Configured point size
|
||||
unsigned int PointSize() const
|
||||
{
|
||||
return myPointSize;
|
||||
return myFontParams.PointSize;
|
||||
}
|
||||
|
||||
//! Compute advance to the next character with kerning applied when applicable.
|
||||
//! Setup glyph scaling along X-axis.
|
||||
//! By default glyphs are not scaled (scaling factor = 1.0)
|
||||
void SetWidthScaling (const float theScaleFactor)
|
||||
{
|
||||
myWidthScaling = theScaleFactor;
|
||||
}
|
||||
|
||||
//! Return TRUE if font contains specified symbol (excluding fallback list).
|
||||
Standard_EXPORT bool HasSymbol (Standard_Utf32Char theUChar) const;
|
||||
|
||||
//! Compute horizontal advance to the next character with kerning applied when applicable.
|
||||
//! Assuming text rendered horizontally.
|
||||
Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUCharNext);
|
||||
//! @param theUCharNext the next character to compute advance from current one
|
||||
Standard_EXPORT float AdvanceX (Standard_Utf32Char theUCharNext) const;
|
||||
|
||||
//! Compute advance to the next character with kerning applied when applicable.
|
||||
//! Compute horizontal advance to the next character with kerning applied when applicable.
|
||||
//! Assuming text rendered horizontally.
|
||||
Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUChar,
|
||||
const Standard_Utf32Char theUCharNext);
|
||||
//! @param theUChar the character to be loaded as current one
|
||||
//! @param theUCharNext the next character to compute advance from current one
|
||||
Standard_EXPORT float AdvanceX (Standard_Utf32Char theUChar,
|
||||
Standard_Utf32Char theUCharNext);
|
||||
|
||||
//! Compute advance to the next character with kerning applied when applicable.
|
||||
//! Compute vertical advance to the next character with kerning applied when applicable.
|
||||
//! Assuming text rendered vertically.
|
||||
Standard_EXPORT float AdvanceY (const Standard_Utf32Char theUCharNext);
|
||||
//! @param theUCharNext the next character to compute advance from current one
|
||||
Standard_EXPORT float AdvanceY (Standard_Utf32Char theUCharNext) const;
|
||||
|
||||
//! Compute advance to the next character with kerning applied when applicable.
|
||||
//! Compute vertical advance to the next character with kerning applied when applicable.
|
||||
//! Assuming text rendered vertically.
|
||||
Standard_EXPORT float AdvanceY (const Standard_Utf32Char theUChar,
|
||||
const Standard_Utf32Char theUCharNext);
|
||||
//! @param theUChar the character to be loaded as current one
|
||||
//! @param theUCharNext the next character to compute advance from current one
|
||||
Standard_EXPORT float AdvanceY (Standard_Utf32Char theUChar,
|
||||
Standard_Utf32Char theUCharNext);
|
||||
|
||||
//! @return glyphs number in this font.
|
||||
Standard_EXPORT Standard_Integer GlyphsNumber() const;
|
||||
//! Return glyphs number in this font.
|
||||
//! @param theToIncludeFallback if TRUE then the number will include fallback list
|
||||
Standard_EXPORT Standard_Integer GlyphsNumber (bool theToIncludeFallback = false) const;
|
||||
|
||||
//! Retrieve glyph bitmap rectangle
|
||||
Standard_EXPORT void GlyphRect (Font_Rect& theRect) const;
|
||||
@@ -131,6 +275,42 @@ public:
|
||||
const Graphic3d_HorizontalTextAlignment theAlignX,
|
||||
const Graphic3d_VerticalTextAlignment theAlignY);
|
||||
|
||||
public:
|
||||
|
||||
//! Initialize the font.
|
||||
//! @param theFontPath path to the font
|
||||
//! @param thePointSize the face size in points (1/72 inch)
|
||||
//! @param theResolution the resolution of the target device in dpi
|
||||
//! @return true on success
|
||||
Standard_DEPRECATED ("Deprecated method, Font_FTFontParams should be used for passing parameters")
|
||||
bool Init (const NCollection_String& theFontPath,
|
||||
unsigned int thePointSize,
|
||||
unsigned int theResolution)
|
||||
{
|
||||
Font_FTFontParams aParams;
|
||||
aParams.PointSize = thePointSize;
|
||||
aParams.Resolution = theResolution;
|
||||
return Init (theFontPath.ToCString(), aParams);
|
||||
}
|
||||
|
||||
//! Initialize the font.
|
||||
//! @param theFontName the font name
|
||||
//! @param theFontAspect the font style
|
||||
//! @param thePointSize the face size in points (1/72 inch)
|
||||
//! @param theResolution the resolution of the target device in dpi
|
||||
//! @return true on success
|
||||
Standard_DEPRECATED ("Deprecated method, Font_FTFontParams should be used for passing parameters")
|
||||
bool Init (const NCollection_String& theFontName,
|
||||
Font_FontAspect theFontAspect,
|
||||
unsigned int thePointSize,
|
||||
unsigned int theResolution)
|
||||
{
|
||||
Font_FTFontParams aParams;
|
||||
aParams.PointSize = thePointSize;
|
||||
aParams.Resolution = theResolution;
|
||||
return FindAndInit (theFontName.ToCString(), theFontAspect, aParams);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! Convert value to 26.6 fixed-point format for FT library API.
|
||||
@@ -152,24 +332,31 @@ protected:
|
||||
//! Load glyph without rendering it.
|
||||
Standard_EXPORT bool loadGlyph (const Standard_Utf32Char theUChar);
|
||||
|
||||
//! Wrapper for FT_Get_Kerning - retrieve kerning values.
|
||||
Standard_EXPORT bool getKerning (FT_Vector& theKern,
|
||||
Standard_Utf32Char theUCharCurr,
|
||||
Standard_Utf32Char theUCharNext) const;
|
||||
|
||||
//! Initialize fallback font.
|
||||
Standard_EXPORT bool findAndInitFallback (Font_UnicodeSubset theSubset);
|
||||
|
||||
protected:
|
||||
|
||||
Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object
|
||||
Handle(NCollection_Buffer) myBuffer; //!< memory buffer
|
||||
Handle(Font_FTFont) myFallbackFaces[Font_UnicodeSubset_NB]; //!< fallback fonts
|
||||
FT_Face myFTFace; //!< FT face object
|
||||
NCollection_String myFontPath; //!< font path
|
||||
unsigned int myPointSize; //!< point size set by FT_Set_Char_Size
|
||||
FT_Face myActiveFTFace; //!< active FT face object (the main of fallback)
|
||||
TCollection_AsciiString myFontPath; //!< font path
|
||||
Font_FTFontParams myFontParams; //!< font initialization parameters
|
||||
Font_FontAspect myFontAspect; //!< font initialization aspect
|
||||
float myWidthScaling; //!< scale glyphs along X-axis
|
||||
int32_t myLoadFlags; //!< default load flags
|
||||
|
||||
Image_PixMap myGlyphImg; //!< cached glyph plane
|
||||
FT_Vector* myKernAdvance; //!< buffer variable
|
||||
Standard_Utf32Char myUChar; //!< currently loaded unicode character
|
||||
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient) // Type definition
|
||||
Standard_Boolean myToUseUnicodeSubsetFallback; //!< use default fallback fonts for extended Unicode sub-sets (Korean, CJK, etc.)
|
||||
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Font_FTFont, Standard_Transient)
|
||||
|
||||
#endif // _Font_FTFont_H__
|
||||
|
@@ -18,11 +18,19 @@
|
||||
//! Specifies aspect of system font.
|
||||
enum Font_FontAspect
|
||||
{
|
||||
Font_FA_Undefined,
|
||||
Font_FA_Regular,
|
||||
Font_FA_Bold,
|
||||
Font_FA_Italic,
|
||||
Font_FA_BoldItalic
|
||||
Font_FontAspect_UNDEFINED = -1, //!< special value reserved for undefined aspect
|
||||
Font_FontAspect_Regular = 0, //!< normal (regular) aspect
|
||||
Font_FontAspect_Bold, //!< bold aspect
|
||||
Font_FontAspect_Italic, //!< italic aspect
|
||||
Font_FontAspect_BoldItalic, //!< bold+italic aspect
|
||||
|
||||
// old aliases
|
||||
Font_FA_Undefined = Font_FontAspect_UNDEFINED,
|
||||
Font_FA_Regular = Font_FontAspect_Regular,
|
||||
Font_FA_Bold = Font_FontAspect_Bold,
|
||||
Font_FA_Italic = Font_FontAspect_Italic,
|
||||
Font_FA_BoldItalic = Font_FontAspect_BoldItalic
|
||||
};
|
||||
enum { Font_FontAspect_NB = Font_FontAspect_BoldItalic + 1 };
|
||||
|
||||
#endif // _Font_FontAspect_HeaderFile
|
||||
|
@@ -13,10 +13,13 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
|
||||
#include <Font_FontMgr.hxx>
|
||||
|
||||
#include <Font_NameOfFont.hxx>
|
||||
#include <Font_FTLibrary.hxx>
|
||||
#include <Font_SystemFont.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <OSD_Environment.hxx>
|
||||
@@ -28,57 +31,6 @@
|
||||
#include FT_FREETYPE_H
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Font_FontMgr,Standard_Transient)
|
||||
|
||||
struct Font_FontMgr_FontAliasMapNode
|
||||
{
|
||||
const char * EnumName;
|
||||
const char * FontName;
|
||||
Font_FontAspect FontAspect;
|
||||
};
|
||||
|
||||
static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] =
|
||||
{
|
||||
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
|
||||
{ "Courier" , "Courier New" , Font_FA_Regular },
|
||||
{ "Times-Roman" , "Times New Roman", Font_FA_Regular },
|
||||
{ "Times-Bold" , "Times New Roman", Font_FA_Bold },
|
||||
{ "Times-Italic" , "Times New Roman", Font_FA_Italic },
|
||||
{ "Times-BoldItalic" , "Times New Roman", Font_FA_BoldItalic },
|
||||
{ "ZapfChancery-MediumItalic", "Script" , Font_FA_Regular },
|
||||
{ "Symbol" , "Symbol" , Font_FA_Regular },
|
||||
{ "ZapfDingbats" , "WingDings" , Font_FA_Regular },
|
||||
{ "Rock" , "Arial" , Font_FA_Regular },
|
||||
{ "Iris" , "Lucida Console" , Font_FA_Regular }
|
||||
|
||||
#elif defined(__ANDROID__)
|
||||
|
||||
{ "Courier" , "Droid Sans Mono", Font_FA_Regular },
|
||||
{ "Times-Roman" , "Droid Serif" , Font_FA_Regular },
|
||||
{ "Times-Bold" , "Droid Serif" , Font_FA_Bold },
|
||||
{ "Times-Italic" , "Droid Serif" , Font_FA_Italic },
|
||||
{ "Times-BoldItalic" , "Droid Serif" , Font_FA_BoldItalic },
|
||||
{ "Arial" , "Roboto" , Font_FA_Regular },
|
||||
|
||||
#else //X11
|
||||
|
||||
{ "Courier" , "Courier" , Font_FA_Regular },
|
||||
{ "Times-Roman" , "Times" , Font_FA_Regular },
|
||||
{ "Times-Bold" , "Times" , Font_FA_Bold },
|
||||
{ "Times-Italic" , "Times" , Font_FA_Italic },
|
||||
{ "Times-BoldItalic" , "Times" , Font_FA_BoldItalic },
|
||||
{ "Arial" , "Helvetica" , Font_FA_Regular },
|
||||
{ "ZapfChancery-MediumItalic", "-adobe-itc zapf chancery-medium-i-normal--*-*-*-*-*-*-iso8859-1" , Font_FA_Regular },
|
||||
{ "Symbol" , "-adobe-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific" , Font_FA_Regular },
|
||||
{ "ZapfDingbats" , "-adobe-itc zapf dingbats-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific" , Font_FA_Regular },
|
||||
{ "Rock" , "-sgi-rock-medium-r-normal--*-*-*-*-p-*-iso8859-1" , Font_FA_Regular },
|
||||
{ "Iris" , "--iris-medium-r-normal--*-*-*-*-m-*-iso8859-1" , Font_FA_Regular }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#define NUM_FONT_ENTRIES (int)(sizeof(Font_FontMgr_MapOfFontsAliases)/sizeof(Font_FontMgr_FontAliasMapNode))
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
@@ -136,6 +88,10 @@ static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] =
|
||||
"/usr/X11/lib/X11/fs/config",
|
||||
NULL
|
||||
};
|
||||
|
||||
// Although fontconfig library can be built for various platforms,
|
||||
// practically it is useful only on desktop Linux distributions, where it is always packaged.
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -215,9 +171,10 @@ static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib
|
||||
if (aFontFace->family_name != NULL // skip broken fonts (error in FreeType?)
|
||||
&& FT_Select_Charmap (aFontFace, ft_encoding_unicode) == 0) // Font_FTFont supports only UNICODE fonts
|
||||
{
|
||||
Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aFontFace->family_name);
|
||||
Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (theFontPath);
|
||||
aResult = new Font_SystemFont (aFontName, anAspect, aFontPath);
|
||||
aResult = new Font_SystemFont (aFontFace->family_name);
|
||||
aResult->SetFontPath (anAspect, theFontPath);
|
||||
// automatically identify some known single-line fonts
|
||||
aResult->SetSingleStrokeFont (aResult->FontKey().StartsWith ("olf "));
|
||||
}
|
||||
|
||||
FT_Done_Face (aFontFace);
|
||||
@@ -240,12 +197,147 @@ Handle(Font_FontMgr) Font_FontMgr::GetInstance()
|
||||
return _mgr;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ToUseUnicodeSubsetFallback
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean& Font_FontMgr::ToUseUnicodeSubsetFallback()
|
||||
{
|
||||
static Standard_Boolean TheToUseUnicodeSubsetFallback = true;
|
||||
return TheToUseUnicodeSubsetFallback;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : addFontAlias
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Font_FontMgr::addFontAlias (const TCollection_AsciiString& theAliasName,
|
||||
const Handle(Font_FontAliasSequence)& theAliases,
|
||||
Font_FontAspect theAspect)
|
||||
{
|
||||
if (theAliases.IsNull()
|
||||
|| theAliases->IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Handle(Font_FontAliasSequence) anAliases = theAliases;
|
||||
if (theAspect != Font_FA_Undefined)
|
||||
{
|
||||
anAliases = new Font_FontAliasSequence();
|
||||
for (Font_FontAliasSequence::Iterator anAliasIter (*theAliases); anAliasIter.More(); anAliasIter.Next())
|
||||
{
|
||||
const TCollection_AsciiString& aName = anAliasIter.Value().FontName;
|
||||
anAliases->Append (Font_FontAlias (aName, theAspect));
|
||||
}
|
||||
}
|
||||
|
||||
TCollection_AsciiString anAliasName (theAliasName);
|
||||
anAliasName.LowerCase();
|
||||
myFontAliases.Bind (anAliasName, anAliases);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Font_FontMgr
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Font_FontMgr::Font_FontMgr()
|
||||
: myToTraceAliases (Standard_False)
|
||||
{
|
||||
Handle(Font_FontAliasSequence) aMono = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aSerif = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aSans = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aSymbol = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aScript = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aWinDin = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) anIris = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aCJK = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) aKorean = new Font_FontAliasSequence();
|
||||
Handle(Font_FontAliasSequence) anArab = new Font_FontAliasSequence();
|
||||
|
||||
// best matches - pre-installed on Windows, some of them are pre-installed on macOS,
|
||||
// and sometimes them can be found installed on other systems (by user)
|
||||
aMono ->Append (Font_FontAlias ("courier new"));
|
||||
aSerif ->Append (Font_FontAlias ("times new roman"));
|
||||
aSans ->Append (Font_FontAlias ("arial"));
|
||||
aSymbol->Append (Font_FontAlias ("symbol"));
|
||||
aScript->Append (Font_FontAlias ("script"));
|
||||
aWinDin->Append (Font_FontAlias ("wingdings"));
|
||||
anIris ->Append (Font_FontAlias ("lucida console"));
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
// Noto font family is usually installed on Android 6+ devices
|
||||
aMono ->Append (Font_FontAlias ("noto mono"));
|
||||
aSerif ->Append (Font_FontAlias ("noto serif"));
|
||||
// Droid font family is usually installed on Android 4+ devices
|
||||
aMono ->Append (Font_FontAlias ("droid sans mono"));
|
||||
aSerif ->Append (Font_FontAlias ("droid serif"));
|
||||
aSans ->Append (Font_FontAlias ("roboto")); // actually DroidSans.ttf
|
||||
#elif !defined(_WIN32) && !defined(__APPLE__) //X11
|
||||
aSerif ->Append (Font_FontAlias ("times"));
|
||||
aSans ->Append (Font_FontAlias ("helvetica"));
|
||||
// GNU FreeFonts family is usually installed on Linux
|
||||
aMono ->Append (Font_FontAlias ("freemono"));
|
||||
aSerif ->Append (Font_FontAlias ("freeserif"));
|
||||
aSans ->Append (Font_FontAlias ("freesans"));
|
||||
// DejaVu font family is usually installed on Linux
|
||||
aMono ->Append (Font_FontAlias ("dejavu sans mono"));
|
||||
aSerif ->Append (Font_FontAlias ("dejavu serif"));
|
||||
aSans ->Append (Font_FontAlias ("dejavu sans"));
|
||||
#endif
|
||||
|
||||
// default CJK (Chinese/Japanese/Korean) fonts
|
||||
aCJK ->Append (Font_FontAlias ("simsun")); // Windows
|
||||
aCJK ->Append (Font_FontAlias ("droid sans fallback")); // Android, Linux
|
||||
aCJK ->Append (Font_FontAlias ("noto sans sc")); // Android
|
||||
|
||||
#if defined(_WIN32)
|
||||
aKorean->Append (Font_FontAlias ("malgun gothic")); // introduced since Vista
|
||||
aKorean->Append (Font_FontAlias ("gulim")); // used on older systems (Windows XP)
|
||||
#elif defined(__APPLE__)
|
||||
aKorean->Append (Font_FontAlias ("applegothic"));
|
||||
aKorean->Append (Font_FontAlias ("stfangsong"));
|
||||
#endif
|
||||
aKorean->Append (Font_FontAlias ("nanumgothic")); // Android, Linux
|
||||
aKorean->Append (Font_FontAlias ("noto sans kr")); // Android
|
||||
aKorean->Append (Font_FontAlias ("nanummyeongjo")); // Linux
|
||||
aKorean->Append (Font_FontAlias ("noto serif cjk jp")); // Linux
|
||||
aKorean->Append (Font_FontAlias ("noto sans cjk jp")); // Linux
|
||||
|
||||
#if defined(_WIN32)
|
||||
anArab->Append (Font_FontAlias ("times new roman"));
|
||||
#elif defined(__APPLE__)
|
||||
anArab->Append (Font_FontAlias ("decotype naskh"));
|
||||
#elif defined(__ANDROID__)
|
||||
anArab->Append (Font_FontAlias ("droid arabic naskh"));
|
||||
anArab->Append (Font_FontAlias ("noto naskh arabic"));
|
||||
#endif
|
||||
|
||||
addFontAlias ("mono", aMono);
|
||||
addFontAlias ("courier", aMono); // Font_NOF_ASCII_MONO
|
||||
addFontAlias ("monospace", aMono); // Font_NOF_MONOSPACE
|
||||
addFontAlias ("rock", aSans); // Font_NOF_CARTOGRAPHIC_SIMPLEX
|
||||
addFontAlias ("sansserif", aSans); // Font_NOF_SANS_SERIF
|
||||
addFontAlias ("sans-serif", aSans);
|
||||
addFontAlias ("sans", aSans);
|
||||
addFontAlias ("arial", aSans);
|
||||
addFontAlias ("times", aSerif);
|
||||
addFontAlias ("serif", aSerif); // Font_NOF_SERIF
|
||||
addFontAlias ("times-roman", aSerif); // Font_NOF_ASCII_SIMPLEX
|
||||
addFontAlias ("times-bold", aSerif, Font_FA_Bold); // Font_NOF_ASCII_DUPLEX
|
||||
addFontAlias ("times-italic", aSerif, Font_FA_Italic); // Font_NOF_ASCII_ITALIC_COMPLEX
|
||||
addFontAlias ("times-bolditalic", aSerif, Font_FA_BoldItalic); // Font_NOF_ASCII_ITALIC_TRIPLEX
|
||||
addFontAlias ("symbol", aSymbol); // Font_NOF_GREEK_MONO
|
||||
addFontAlias ("iris", anIris); // Font_NOF_KANJI_MONO
|
||||
addFontAlias ("korean", aKorean); // Font_NOF_KOREAN
|
||||
addFontAlias ("cjk", aCJK); // Font_NOF_CJK
|
||||
addFontAlias ("nsimsun", aCJK);
|
||||
addFontAlias ("arabic", anArab); // Font_NOF_ARABIC
|
||||
addFontAlias (Font_NOF_SYMBOL_MONO, aWinDin);
|
||||
addFontAlias (Font_NOF_ASCII_SCRIPT_SIMPLEX, aScript);
|
||||
|
||||
myFallbackAlias = aSans;
|
||||
|
||||
InitFontDataBase();
|
||||
}
|
||||
|
||||
@@ -271,39 +363,30 @@ Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theF
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
for (Font_NListOfSystemFont::Iterator aFontIter (myListOfFonts);
|
||||
aFontIter.More(); aFontIter.Next())
|
||||
{
|
||||
if (!aFontIter.Value()->FontName()->IsSameString (theFont->FontName(), Standard_False))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (theFont->FontAspect() != Font_FA_Undefined
|
||||
&& aFontIter.Value()->FontAspect() != theFont->FontAspect())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (theFont->FontHeight() == -1 || aFontIter.Value()->FontHeight() == -1
|
||||
|| theFont->FontHeight() == aFontIter.Value()->FontHeight())
|
||||
{
|
||||
if (theFont->FontPath()->String() == aFontIter.Value()->FontPath()->String())
|
||||
const Standard_Integer anOldIndex = myFontMap.FindIndex (theFont);
|
||||
if (anOldIndex == 0)
|
||||
{
|
||||
myFontMap.Add (theFont);
|
||||
return Standard_True;
|
||||
}
|
||||
else if (theToOverride)
|
||||
|
||||
Handle(Font_SystemFont) anOldFont = myFontMap.FindKey (anOldIndex);
|
||||
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
|
||||
{
|
||||
myListOfFonts.Remove (aFontIter);
|
||||
if (anOldFont->FontPath ((Font_FontAspect )anAspectIter).IsEqual (theFont->FontPath ((Font_FontAspect )anAspectIter)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
else if (theToOverride
|
||||
|| !anOldFont->HasFontAspect ((Font_FontAspect )anAspectIter))
|
||||
{
|
||||
anOldFont->SetFontPath ((Font_FontAspect )anAspectIter, theFont->FontPath ((Font_FontAspect )anAspectIter));
|
||||
}
|
||||
else if (theFont->HasFontAspect ((Font_FontAspect )anAspectIter))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myListOfFonts.Append (theFont);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
@@ -313,8 +396,8 @@ Standard_Boolean Font_FontMgr::RegisterFont (const Handle(Font_SystemFont)& theF
|
||||
// =======================================================================
|
||||
void Font_FontMgr::InitFontDataBase()
|
||||
{
|
||||
myListOfFonts.Clear();
|
||||
Handle(Font_FTLibrary) aFtLibrary;
|
||||
myFontMap.Clear();
|
||||
Handle(Font_FTLibrary) aFtLibrary = new Font_FTLibrary();
|
||||
|
||||
#if defined(OCCT_UWP)
|
||||
// system font files are not accessible
|
||||
@@ -330,8 +413,8 @@ void Font_FontMgr::InitFontDataBase()
|
||||
|
||||
char* aWinDir = new char[aStrLength];
|
||||
GetSystemWindowsDirectoryA (aWinDir, aStrLength);
|
||||
Handle(TCollection_HAsciiString) aFontsDir = new TCollection_HAsciiString (aWinDir);
|
||||
aFontsDir->AssignCat ("\\Fonts\\");
|
||||
TCollection_AsciiString aFontsDir (aWinDir);
|
||||
aFontsDir.AssignCat ("\\Fonts\\");
|
||||
delete[] aWinDir;
|
||||
|
||||
// read fonts list from registry
|
||||
@@ -349,7 +432,6 @@ void Font_FontMgr::InitFontDataBase()
|
||||
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
||||
}
|
||||
|
||||
aFtLibrary = new Font_FTLibrary();
|
||||
static const DWORD aBufferSize = 256;
|
||||
char aNameBuff[aBufferSize];
|
||||
char aPathBuff[aBufferSize];
|
||||
@@ -363,25 +445,23 @@ void Font_FontMgr::InitFontDataBase()
|
||||
{
|
||||
aPathBuff[(aPathSize < aBufferSize) ? aPathSize : (aBufferSize - 1)] = '\0'; // ensure string is NULL-terminated
|
||||
|
||||
Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aNameBuff);
|
||||
Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (aPathBuff);
|
||||
if (aFontPath->Search ("\\") == -1)
|
||||
TCollection_AsciiString aFontName (aNameBuff), aFontPath (aPathBuff);
|
||||
if (aFontPath.Search ("\\") == -1)
|
||||
{
|
||||
aFontPath->Insert (1, aFontsDir); // make absolute path
|
||||
aFontPath.Insert (1, aFontsDir); // make absolute path
|
||||
}
|
||||
|
||||
// check file extension is in list of supported
|
||||
const Standard_Integer anExtensionPosition = aFontPath->SearchFromEnd (".") + 1;
|
||||
if (anExtensionPosition > 0 && anExtensionPosition < aFontPath->Length())
|
||||
const Standard_Integer anExtensionPosition = aFontPath.SearchFromEnd (".") + 1;
|
||||
if (anExtensionPosition > 0 && anExtensionPosition < aFontPath.Length())
|
||||
{
|
||||
Handle(TCollection_HAsciiString) aFontExtension = aFontPath->SubString (anExtensionPosition, aFontPath->Length());
|
||||
aFontExtension->LowerCase();
|
||||
if (aSupportedExtensions.Contains (aFontExtension->String()))
|
||||
TCollection_AsciiString aFontExtension = aFontPath.SubString (anExtensionPosition, aFontPath.Length());
|
||||
aFontExtension.LowerCase();
|
||||
if (aSupportedExtensions.Contains (aFontExtension))
|
||||
{
|
||||
Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath->ToCString());
|
||||
if (!aNewFont.IsNull())
|
||||
if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath.ToCString()))
|
||||
{
|
||||
myListOfFonts.Append (aNewFont);
|
||||
RegisterFont (aNewFont, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -394,7 +474,31 @@ void Font_FontMgr::InitFontDataBase()
|
||||
|
||||
NCollection_Map<TCollection_AsciiString> aMapOfFontsDirs;
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
if (FcConfig* aFcCfg = FcInitLoadConfig())
|
||||
{
|
||||
if (FcStrList* aFcFontDir = FcConfigGetFontDirs (aFcCfg))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
FcChar8* aFcFolder = FcStrListNext (aFcFontDir);
|
||||
if (aFcFolder == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
TCollection_AsciiString aPathStr ((const char* )aFcFolder);
|
||||
OSD_Path aPath (aPathStr);
|
||||
addDirsRecursively (aPath, aMapOfFontsDirs);
|
||||
}
|
||||
FcStrListDone (aFcFontDir);
|
||||
}
|
||||
FcConfigDestroy (aFcCfg);
|
||||
}
|
||||
|
||||
const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
|
||||
if (aMapOfFontsDirs.IsEmpty())
|
||||
{
|
||||
Message::DefaultMessenger()->Send ("Font_FontMgr, fontconfig library returns an empty folder list", Message_Alarm);
|
||||
|
||||
// read fonts directories from font service config file (obsolete)
|
||||
for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
|
||||
@@ -450,6 +554,7 @@ void Font_FontMgr::InitFontDataBase()
|
||||
}
|
||||
aFile.Close();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// append default directories
|
||||
@@ -468,11 +573,14 @@ void Font_FontMgr::InitFontDataBase()
|
||||
aSupportedExtensions.Add (TCollection_AsciiString (anExt));
|
||||
}
|
||||
|
||||
aFtLibrary = new Font_FTLibrary();
|
||||
for (NCollection_Map<TCollection_AsciiString>::Iterator anIter (aMapOfFontsDirs);
|
||||
anIter.More(); anIter.Next())
|
||||
{
|
||||
#if defined(__ANDROID__) || defined(__APPLE__)
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
OSD_File aReadFile (anIter.Value() + "/fonts.dir");
|
||||
if (!aReadFile.Exists())
|
||||
{
|
||||
#endif
|
||||
OSD_Path aFolderPath (anIter.Value());
|
||||
for (OSD_FileIterator aFileIter (aFolderPath, "*"); aFileIter.More(); aFileIter.Next())
|
||||
{
|
||||
@@ -483,17 +591,14 @@ void Font_FontMgr::InitFontDataBase()
|
||||
aFontFilePath.SystemName (aFontFileName);
|
||||
aFontFileName = anIter.Value() + "/" + aFontFileName;
|
||||
|
||||
Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString());
|
||||
if (!aNewFont.IsNull())
|
||||
if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString()))
|
||||
{
|
||||
myListOfFonts.Append (aNewFont);
|
||||
RegisterFont (aNewFont, false);
|
||||
}
|
||||
}
|
||||
#else
|
||||
OSD_File aReadFile (anIter.Value() + "/fonts.dir");
|
||||
if (!aReadFile.Exists())
|
||||
{
|
||||
continue; // invalid fonts directory
|
||||
|
||||
#if !defined(__ANDROID__) && !defined(__APPLE__)
|
||||
continue;
|
||||
}
|
||||
|
||||
aReadFile.Open (OSD_ReadOnly, aProtectRead);
|
||||
@@ -536,34 +641,45 @@ void Font_FontMgr::InitFontDataBase()
|
||||
// In current implementation use fonts with ISO-8859-1 coding page.
|
||||
// OCCT not give to manage coding page by means of programm interface.
|
||||
// TODO: make high level interface for choosing necessary coding page.
|
||||
Handle(TCollection_HAsciiString) aXLFD =
|
||||
new TCollection_HAsciiString (aLine.SubString (anEndOfFileName + 2, aLine.Length()));
|
||||
Handle(TCollection_HAsciiString) aFontPath =
|
||||
new TCollection_HAsciiString (anIter.Value().ToCString());
|
||||
if (aFontPath->SearchFromEnd ("/") != aFontPath->Length())
|
||||
TCollection_AsciiString aXLFD (aLine.SubString (anEndOfFileName + 2, aLine.Length()));
|
||||
TCollection_AsciiString aFontPath (anIter.Value().ToCString());
|
||||
if (aFontPath.SearchFromEnd ("/") != aFontPath.Length())
|
||||
{
|
||||
aFontPath->AssignCat ("/");
|
||||
aFontPath.AssignCat ("/");
|
||||
}
|
||||
TCollection_AsciiString aFontFileName (aLine.SubString (1, anEndOfFileName));
|
||||
aFontPath.AssignCat (aFontFileName);
|
||||
if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath.ToCString()))
|
||||
{
|
||||
RegisterFont (aNewFont, false);
|
||||
if (!aXLFD.IsEmpty()
|
||||
&& aXLFD.Search ("-0-0-0-0-") != -1) // ignore non-resizable fonts
|
||||
{
|
||||
const TCollection_AsciiString anXName = aXLFD.Token ("-", 2);
|
||||
Font_FontAspect anXAspect = Font_FA_Regular;
|
||||
if (aXLFD.Token ("-", 3).IsEqual ("bold")
|
||||
&& (aXLFD.Token ("-", 4).IsEqual ("i")
|
||||
|| aXLFD.Token ("-", 4).IsEqual ("o")))
|
||||
{
|
||||
anXAspect = Font_FA_BoldItalic;
|
||||
}
|
||||
else if (aXLFD.Token ("-", 3).IsEqual ("bold"))
|
||||
{
|
||||
anXAspect = Font_FA_Bold;
|
||||
}
|
||||
else if (aXLFD.Token ("-", 4).IsEqual ("i")
|
||||
|| aXLFD.Token ("-", 4).IsEqual ("o"))
|
||||
{
|
||||
anXAspect = Font_FA_Italic;
|
||||
}
|
||||
Handle(TCollection_HAsciiString) aFontFileName =
|
||||
new TCollection_HAsciiString (aLine.SubString (1, anEndOfFileName));
|
||||
aFontPath->AssignCat (aFontFileName);
|
||||
|
||||
Handle(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (aXLFD, aFontPath);
|
||||
Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath->ToCString());
|
||||
|
||||
if (aNewFontFromXLFD->IsValid() && !aNewFont.IsNull() &&
|
||||
!aNewFont->IsEqual (aNewFontFromXLFD))
|
||||
Handle(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (anXName);
|
||||
aNewFontFromXLFD->SetFontPath (anXAspect, aFontPath);
|
||||
if (!aNewFont->IsEqual (aNewFontFromXLFD))
|
||||
{
|
||||
myListOfFonts.Append (aNewFont);
|
||||
myListOfFonts.Append (aNewFontFromXLFD);
|
||||
RegisterFont (aNewFontFromXLFD, false);
|
||||
}
|
||||
else if (!aNewFont.IsNull())
|
||||
{
|
||||
myListOfFonts.Append (aNewFont);
|
||||
}
|
||||
else if (aNewFontFromXLFD->IsValid())
|
||||
{
|
||||
myListOfFonts.Append (aNewFontFromXLFD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,15 +689,6 @@ void Font_FontMgr::InitFontDataBase()
|
||||
#endif
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetAvailableFonts
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
const Font_NListOfSystemFont& Font_FontMgr::GetAvailableFonts() const
|
||||
{
|
||||
return myListOfFonts;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetAvailableFontsNames
|
||||
// purpose :
|
||||
@@ -589,9 +696,11 @@ const Font_NListOfSystemFont& Font_FontMgr::GetAvailableFonts() const
|
||||
void Font_FontMgr::GetAvailableFontsNames (TColStd_SequenceOfHAsciiString& theFontsNames) const
|
||||
{
|
||||
theFontsNames.Clear();
|
||||
for (Font_NListOfSystemFont::Iterator anIter(myListOfFonts); anIter.More(); anIter.Next())
|
||||
for (NCollection_IndexedMap<Handle(Font_SystemFont), Font_SystemFont>::Iterator aFontIter (myFontMap);
|
||||
aFontIter.More(); aFontIter.Next())
|
||||
{
|
||||
theFontsNames.Append (anIter.Value()->FontName());
|
||||
const Handle(Font_SystemFont)& aFont = aFontIter.Value();
|
||||
theFontsNames.Append (new TCollection_HAsciiString(aFont->FontName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,101 +712,180 @@ Handle(Font_SystemFont) Font_FontMgr::GetFont (const Handle(TCollection_HAsciiSt
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Integer theFontSize) const
|
||||
{
|
||||
if ( (theFontSize < 2 && theFontSize != -1) || theFontName.IsNull())
|
||||
if ((theFontSize < 2 && theFontSize != -1) || theFontName.IsNull())
|
||||
{
|
||||
return NULL;
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
|
||||
for (Font_NListOfSystemFont::Iterator aFontsIterator (myListOfFonts);
|
||||
aFontsIterator.More(); aFontsIterator.Next())
|
||||
{
|
||||
if (!theFontName->IsEmpty() && !aFontsIterator.Value()->FontName()->IsSameString (theFontName, Standard_False))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Handle(Font_SystemFont) aFont = myFontMap.Find (theFontName->String());
|
||||
return (aFont.IsNull()
|
||||
|| theFontAspect == Font_FontAspect_UNDEFINED
|
||||
|| aFont->HasFontAspect (theFontAspect))
|
||||
? aFont
|
||||
: Handle(Font_SystemFont)();
|
||||
}
|
||||
|
||||
if (theFontAspect != Font_FA_Undefined && aFontsIterator.Value()->FontAspect() != theFontAspect)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// =======================================================================
|
||||
// function : GetFont
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(Font_SystemFont) Font_FontMgr::GetFont (const TCollection_AsciiString& theFontName) const
|
||||
{
|
||||
return myFontMap.Find (theFontName);
|
||||
}
|
||||
|
||||
if (theFontSize == -1 || aFontsIterator.Value()->FontHeight() == -1 ||
|
||||
theFontSize == aFontsIterator.Value()->FontHeight())
|
||||
// =======================================================================
|
||||
// function : FindFallbackFont
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(Font_SystemFont) Font_FontMgr::FindFallbackFont (Font_UnicodeSubset theSubset,
|
||||
Font_FontAspect theFontAspect) const
|
||||
{
|
||||
Font_FontAspect aFontAspect = theFontAspect;
|
||||
switch (theSubset)
|
||||
{
|
||||
return aFontsIterator.Value();
|
||||
case Font_UnicodeSubset_Western: return FindFont (Font_NOF_SANS_SERIF, Font_StrictLevel_Aliases, aFontAspect);
|
||||
case Font_UnicodeSubset_Korean: return FindFont (Font_NOF_KOREAN, Font_StrictLevel_Aliases, aFontAspect);
|
||||
case Font_UnicodeSubset_CJK: return FindFont (Font_NOF_CJK, Font_StrictLevel_Aliases, aFontAspect);
|
||||
case Font_UnicodeSubset_Arabic: return FindFont (Font_NOF_ARABIC, Font_StrictLevel_Aliases, aFontAspect);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : FindFont
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(Font_SystemFont) Font_FontMgr::FindFont (const Handle(TCollection_HAsciiString)& theFontName,
|
||||
const Font_FontAspect theFontAspect,
|
||||
const Standard_Integer theFontSize) const
|
||||
Handle(Font_SystemFont) Font_FontMgr::FindFont (const TCollection_AsciiString& theFontName,
|
||||
Font_StrictLevel theStrictLevel,
|
||||
Font_FontAspect& theFontAspect) const
|
||||
{
|
||||
Handle(TCollection_HAsciiString) aFontName = theFontName;
|
||||
Font_FontAspect aFontAspect = theFontAspect;
|
||||
Standard_Integer aFontSize = theFontSize;
|
||||
|
||||
Handle(Font_SystemFont) aFont = GetFont (aFontName, aFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
TCollection_AsciiString aFontName (theFontName);
|
||||
aFontName.LowerCase();
|
||||
Handle(Font_SystemFont) aFont = myFontMap.Find (aFontName);
|
||||
if (!aFont.IsNull()
|
||||
|| theStrictLevel == Font_StrictLevel_Strict)
|
||||
{
|
||||
return aFont;
|
||||
}
|
||||
|
||||
// Trying to use font names mapping
|
||||
for (Standard_Integer anIter = 0; anIter < NUM_FONT_ENTRIES; ++anIter)
|
||||
for (int aPass = 0; aPass < 2; ++aPass)
|
||||
{
|
||||
Handle(TCollection_HAsciiString) aFontAlias =
|
||||
new TCollection_HAsciiString (Font_FontMgr_MapOfFontsAliases[anIter].EnumName);
|
||||
Handle(Font_FontAliasSequence) anAliases;
|
||||
if (aPass == 0)
|
||||
{
|
||||
myFontAliases.Find (aFontName, anAliases);
|
||||
}
|
||||
else if (theStrictLevel == Font_StrictLevel_Any)
|
||||
{
|
||||
anAliases = myFallbackAlias;
|
||||
}
|
||||
|
||||
if (aFontAlias->IsSameString (aFontName, Standard_False))
|
||||
if (anAliases.IsNull()
|
||||
|| anAliases->IsEmpty())
|
||||
{
|
||||
aFontName = new TCollection_HAsciiString (Font_FontMgr_MapOfFontsAliases[anIter].FontName);
|
||||
aFontAspect = Font_FontMgr_MapOfFontsAliases[anIter].FontAspect;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isAliasUsed = false, isBestAlias = false;
|
||||
for (Font_FontAliasSequence::Iterator anAliasIter (*anAliases); anAliasIter.More(); anAliasIter.Next())
|
||||
{
|
||||
const Font_FontAlias& anAlias = anAliasIter.Value();
|
||||
if (Handle(Font_SystemFont) aFont2 = myFontMap.Find (anAlias.FontName))
|
||||
{
|
||||
if (aFont.IsNull())
|
||||
{
|
||||
aFont = aFont2;
|
||||
isAliasUsed = true;
|
||||
}
|
||||
|
||||
if ((anAlias.FontAspect != Font_FontAspect_UNDEFINED
|
||||
&& aFont2->HasFontAspect (anAlias.FontAspect)))
|
||||
{
|
||||
// special case - alias refers to styled font (e.g. "times-bold")
|
||||
isBestAlias = true;
|
||||
theFontAspect = anAlias.FontAspect;
|
||||
break;
|
||||
}
|
||||
else if (anAlias.FontAspect == Font_FontAspect_UNDEFINED
|
||||
&& (theFontAspect == Font_FontAspect_UNDEFINED
|
||||
|| aFont2->HasFontAspect (theFontAspect)))
|
||||
{
|
||||
isBestAlias = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check font family alias with specified font aspect
|
||||
if (theFontAspect != Font_FA_Undefined
|
||||
&& theFontAspect != Font_FA_Regular
|
||||
&& theFontAspect != aFontAspect)
|
||||
if (aPass == 0)
|
||||
{
|
||||
aFont = GetFont (aFontName, theFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
if (isAliasUsed && myToTraceAliases)
|
||||
{
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, using font alias '") + aFont->FontName() + "'"
|
||||
" instead of requested '" + theFontName +"'", Message_Trace);
|
||||
}
|
||||
if (isBestAlias)
|
||||
{
|
||||
return aFont;
|
||||
}
|
||||
}
|
||||
|
||||
// check font alias with aspect in the name
|
||||
aFont = GetFont (aFontName, aFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
else if (!aFont.IsNull())
|
||||
{
|
||||
return aFont;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Requested family name not found -> search for any font family with given aspect and height
|
||||
aFontName = new TCollection_HAsciiString ("");
|
||||
aFont = GetFont (aFontName, aFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
if (aFont.IsNull()
|
||||
&& theStrictLevel == Font_StrictLevel_Any)
|
||||
{
|
||||
return aFont;
|
||||
// try finding ANY font in case if even default fallback alias myFallbackAlias cannot be found
|
||||
aFont = myFontMap.Find (TCollection_AsciiString());
|
||||
}
|
||||
|
||||
// The last resort: trying to use ANY font available in the system
|
||||
aFontAspect = Font_FA_Undefined;
|
||||
aFontSize = -1;
|
||||
aFont = GetFont (aFontName, aFontAspect, aFontSize);
|
||||
if (!aFont.IsNull())
|
||||
if (aFont.IsNull())
|
||||
{
|
||||
return aFont;
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, error: unable to find any font!", Message_Fail));
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
|
||||
return NULL; // Fonts are not found in the system.
|
||||
if ((theFontAspect != Font_FA_Undefined
|
||||
&& !aFont->HasFontAspect (theFontAspect))
|
||||
|| (!aFontName.IsEmpty()
|
||||
&& !aFontName.IsEqual (aFont->FontKey())))
|
||||
{
|
||||
TCollection_AsciiString aDesc = TCollection_AsciiString() + "'" + theFontName + "'"
|
||||
+ TCollection_AsciiString() + " [" + Font_FontMgr::FontAspectToString (theFontAspect) + "]";
|
||||
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, warning: unable to find font ")
|
||||
+ aDesc + "; " + aFont->ToString() + " is used instead");
|
||||
}
|
||||
return aFont;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Font_FontMap::Find
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Handle(Font_SystemFont) Font_FontMgr::Font_FontMap::Find (const TCollection_AsciiString& theFontName) const
|
||||
{
|
||||
if (IsEmpty())
|
||||
{
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
else if (theFontName.IsEmpty())
|
||||
{
|
||||
return FindKey (1); // return any font
|
||||
}
|
||||
|
||||
TCollection_AsciiString aFontName (theFontName);
|
||||
aFontName.LowerCase();
|
||||
for (IndexedMapNode* aNodeIter = (IndexedMapNode* )myData1[::HashCode (aFontName, NbBuckets())];
|
||||
aNodeIter != NULL; aNodeIter = (IndexedMapNode* )aNodeIter->Next())
|
||||
{
|
||||
const Handle(Font_SystemFont)& aKey = aNodeIter->Key1();
|
||||
if (aKey->FontKey().IsEqual (aFontName))
|
||||
{
|
||||
return aKey;
|
||||
}
|
||||
}
|
||||
return Handle(Font_SystemFont)();
|
||||
}
|
||||
|
@@ -17,32 +17,66 @@
|
||||
#define _Font_FontMgr_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include <Font_NListOfSystemFont.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <TColStd_SequenceOfHAsciiString.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Standard_CString.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <Font_NListOfSystemFont.hxx>
|
||||
#include <Font_StrictLevel.hxx>
|
||||
#include <Font_UnicodeSubset.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_IndexedMap.hxx>
|
||||
#include <NCollection_Shared.hxx>
|
||||
#include <TColStd_SequenceOfHAsciiString.hxx>
|
||||
|
||||
class Font_SystemFont;
|
||||
class TCollection_HAsciiString;
|
||||
|
||||
|
||||
class Font_FontMgr;
|
||||
DEFINE_STANDARD_HANDLE(Font_FontMgr, Standard_Transient)
|
||||
|
||||
//! Collects and provides information about available fonts in system.
|
||||
class Font_FontMgr : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Font_FontMgr, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Return global instance of font manager.
|
||||
Standard_EXPORT static Handle(Font_FontMgr) GetInstance();
|
||||
|
||||
//! Return font aspect as string.
|
||||
static const char* FontAspectToString (Font_FontAspect theAspect)
|
||||
{
|
||||
switch (theAspect)
|
||||
{
|
||||
case Font_FontAspect_UNDEFINED: return "undefined";
|
||||
case Font_FontAspect_Regular: return "regular";
|
||||
case Font_FontAspect_Bold: return "bold";
|
||||
case Font_FontAspect_Italic: return "italic";
|
||||
case Font_FontAspect_BoldItalic: return "bold-italic";
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
//! Return flag to use fallback fonts in case if used font does not include symbols from specific Unicode subset; TRUE by default.
|
||||
Standard_EXPORT static Standard_Boolean& ToUseUnicodeSubsetFallback();
|
||||
|
||||
public:
|
||||
|
||||
//! Return the list of available fonts.
|
||||
void AvailableFonts (Font_NListOfSystemFont& theList) const
|
||||
{
|
||||
for (Font_FontMap::Iterator aFontIter (myFontMap); aFontIter.More(); aFontIter.Next())
|
||||
{
|
||||
theList.Append (aFontIter.Value());
|
||||
}
|
||||
}
|
||||
|
||||
Standard_EXPORT static Handle(Font_FontMgr) GetInstance();
|
||||
|
||||
Standard_EXPORT const Font_NListOfSystemFont& GetAvailableFonts() const;
|
||||
//! Return the list of available fonts.
|
||||
Font_NListOfSystemFont GetAvailableFonts() const
|
||||
{
|
||||
Font_NListOfSystemFont aList;
|
||||
AvailableFonts (aList);
|
||||
return aList;
|
||||
}
|
||||
|
||||
//! Returns sequence of available fonts names
|
||||
Standard_EXPORT void GetAvailableFontsNames (TColStd_SequenceOfHAsciiString& theFontsNames) const;
|
||||
@@ -53,50 +87,118 @@ public:
|
||||
//! If theFontSize is "-1" returned font can have any FontSize.
|
||||
Standard_EXPORT Handle(Font_SystemFont) GetFont (const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Standard_Integer theFontSize) const;
|
||||
|
||||
//! Returns font that match given name or NULL if such font family is NOT registered.
|
||||
//! Note that unlike FindFont(), this method ignores font aliases and does not look for fall-back.
|
||||
Standard_EXPORT Handle(Font_SystemFont) GetFont (const TCollection_AsciiString& theFontName) const;
|
||||
|
||||
//! Tries to find font by given parameters.
|
||||
//! If the specified font is not found tries to use font names mapping.
|
||||
//! If the requested family name not found -> search for any font family
|
||||
//! with given aspect and height. If the font is still not found, returns
|
||||
//! any font available in the system. Returns NULL in case when the fonts
|
||||
//! are not found in the system.
|
||||
Standard_EXPORT Handle(Font_SystemFont) FindFont (const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Standard_Integer theFontSize) const;
|
||||
//! If the requested family name not found -> search for any font family with given aspect and height.
|
||||
//! If the font is still not found, returns any font available in the system.
|
||||
//! Returns NULL in case when the fonts are not found in the system.
|
||||
//! @param theFontName [in] font family to find or alias name
|
||||
//! @param theStrictLevel [in] search strict level for using aliases and fallback
|
||||
//! @param theFontAspect [in] [out] font aspect to find (considered only if family name is not found);
|
||||
//! can be modified if specified font alias refers to another style (compatibility with obsolete aliases)
|
||||
Standard_EXPORT Handle(Font_SystemFont) FindFont (const TCollection_AsciiString& theFontName,
|
||||
Font_StrictLevel theStrictLevel,
|
||||
Font_FontAspect& theFontAspect) const;
|
||||
|
||||
//! Tries to find font by given parameters.
|
||||
Handle(Font_SystemFont) FindFont (const TCollection_AsciiString& theFontName,
|
||||
Font_FontAspect& theFontAspect) const
|
||||
{
|
||||
return FindFont (theFontName, Font_StrictLevel_Any, theFontAspect);
|
||||
}
|
||||
|
||||
//! Tries to find fallback font for specified Unicode subset.
|
||||
//! Returns NULL in case when fallback font is not found in the system.
|
||||
//! @param theSubset [in] Unicode subset
|
||||
//! @param theFontAspect [in] font aspect to find
|
||||
Standard_EXPORT Handle(Font_SystemFont) FindFallbackFont (Font_UnicodeSubset theSubset,
|
||||
Font_FontAspect theFontAspect) const;
|
||||
|
||||
//! Read font file and retrieve information from it.
|
||||
Standard_EXPORT Handle(Font_SystemFont) CheckFont (const Standard_CString theFontPath) const;
|
||||
|
||||
//! Register new font.
|
||||
//! If there is existing entity with the same name and properties but different path
|
||||
//! then font will will be overridden or ignored depending on theToOverride flag.
|
||||
//! then font will be overridden or ignored depending on theToOverride flag.
|
||||
Standard_EXPORT Standard_Boolean RegisterFont (const Handle(Font_SystemFont)& theFont, const Standard_Boolean theToOverride);
|
||||
|
||||
//! Return flag for tracing font aliases usage via Message_Trace messages; TRUE by default.
|
||||
Standard_Boolean ToTraceAliases() const { return myToTraceAliases; }
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Font_FontMgr,Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
//! Set flag for tracing font alias usage; useful to trace which fonts are actually used.
|
||||
//! Can be disabled to avoid redundant messages with Message_Trace level.
|
||||
void SetTraceAliases (Standard_Boolean theToTrace) { myToTraceAliases = theToTrace; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
//! Creates empty font object
|
||||
//! Creates empty font manager object
|
||||
Standard_EXPORT Font_FontMgr();
|
||||
|
||||
//! Collects available fonts paths.
|
||||
Standard_EXPORT void InitFontDataBase();
|
||||
|
||||
Font_NListOfSystemFont myListOfFonts;
|
||||
private:
|
||||
|
||||
//! Map storing registered fonts.
|
||||
class Font_FontMap : public NCollection_IndexedMap<Handle(Font_SystemFont), Font_SystemFont>
|
||||
{
|
||||
public:
|
||||
//! Empty constructor.
|
||||
Font_FontMap() {}
|
||||
|
||||
//! Try finding font with specified parameters or the closest one.
|
||||
//! @param theFontName [in] font family to find (or empty string if family name can be ignored)
|
||||
//! @return best match font or NULL if not found
|
||||
Handle(Font_SystemFont) Find (const TCollection_AsciiString& theFontName) const;
|
||||
|
||||
public:
|
||||
|
||||
//! Hash value, for Map interface.
|
||||
//! Based on Font Family, so that the whole family with different aspects can be found within the same bucket.
|
||||
static Standard_Integer HashCode (const Handle(Font_SystemFont)& theFont,
|
||||
const Standard_Integer theUpper)
|
||||
{
|
||||
return ::HashCode (theFont->FontKey(), theUpper);
|
||||
}
|
||||
|
||||
//! Matching two instances, for Map interface.
|
||||
static bool IsEqual (const Handle(Font_SystemFont)& theFont1,
|
||||
const Handle(Font_SystemFont)& theFont2)
|
||||
{
|
||||
return theFont1->IsEqual (theFont2);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//! Structure defining font alias.
|
||||
struct Font_FontAlias
|
||||
{
|
||||
TCollection_AsciiString FontName;
|
||||
Font_FontAspect FontAspect;
|
||||
|
||||
Font_FontAlias (const TCollection_AsciiString& theFontName, Font_FontAspect theFontAspect = Font_FontAspect_UNDEFINED) : FontName (theFontName), FontAspect (theFontAspect) {}
|
||||
Font_FontAlias() : FontAspect (Font_FontAspect_UNDEFINED) {}
|
||||
};
|
||||
|
||||
//! Sequence of font aliases.
|
||||
typedef NCollection_Shared< NCollection_Sequence<Font_FontAlias> > Font_FontAliasSequence;
|
||||
|
||||
//! Register font alias.
|
||||
void addFontAlias (const TCollection_AsciiString& theAliasName,
|
||||
const Handle(Font_FontAliasSequence)& theAliases,
|
||||
Font_FontAspect theAspect = Font_FontAspect_UNDEFINED);
|
||||
|
||||
private:
|
||||
|
||||
Font_FontMap myFontMap;
|
||||
NCollection_DataMap<TCollection_AsciiString, Handle(Font_FontAliasSequence)> myFontAliases;
|
||||
Handle(Font_FontAliasSequence) myFallbackAlias;
|
||||
Standard_Boolean myToTraceAliases;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _Font_FontMgr_HeaderFile
|
||||
|
@@ -13,6 +13,13 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#define Font_NOF_MONOSPACE "monospace"
|
||||
#define Font_NOF_SERIF "serif"
|
||||
#define Font_NOF_SANS_SERIF "sans-serif"
|
||||
#define Font_NOF_CJK "cjk" // Font_UnicodeSubset_CJK
|
||||
#define Font_NOF_KOREAN "korean" // Font_UnicodeSubset_Korean
|
||||
#define Font_NOF_ARABIC "arabic" // Font_UnicodeSubset_Arabic
|
||||
|
||||
#define Font_NOF_ASCII_MONO "Courier"
|
||||
#define Font_NOF_ASCII_SIMPLEX "Times-Roman"
|
||||
#define Font_NOF_ASCII_COMPLEX "Times-Roman"
|
||||
|
@@ -1,7 +1,4 @@
|
||||
// Created on: 1992-08-18
|
||||
// Created by: Herve LEGRAND
|
||||
// Copyright (c) 1992-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
// Copyright (c) 2019 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
@@ -14,7 +11,15 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _Font_StrictLevel_HeaderFile
|
||||
#define _Font_StrictLevel_HeaderFile
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <HLRBRep_SLPropsATool.hxx>
|
||||
//! Enumeration defining font search restrictions.
|
||||
enum Font_StrictLevel
|
||||
{
|
||||
Font_StrictLevel_Strict, //!< search only for exact font
|
||||
Font_StrictLevel_Aliases, //!< search for exact font match and for aliases (ignore global fallback)
|
||||
Font_StrictLevel_Any, //!< search for any font, including global fallback
|
||||
};
|
||||
|
||||
#endif // _Font_StrictLevel_HeaderFile
|
@@ -13,126 +13,96 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
// Updated:
|
||||
|
||||
#include <Font_SystemFont.hxx>
|
||||
|
||||
#include <Font_FontMgr.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont,Standard_Transient)
|
||||
IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient)
|
||||
|
||||
Font_SystemFont::Font_SystemFont():
|
||||
MyFontName(),
|
||||
MyFontAspect(Font_FA_Undefined),
|
||||
MyFaceSize(-1),
|
||||
MyVerification(Standard_False)
|
||||
// =======================================================================
|
||||
// function : Font_SystemFont
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Font_SystemFont::Font_SystemFont (const TCollection_AsciiString& theFontName)
|
||||
: myFontKey (theFontName),
|
||||
myFontName (theFontName),
|
||||
myIsSingleLine (Standard_False)
|
||||
{
|
||||
if (theFontName.IsEmpty()) { throw Standard_ProgramError ("Font_SystemFont constructor called with empty font name"); }
|
||||
myFontKey.LowerCase();
|
||||
}
|
||||
|
||||
Font_SystemFont::Font_SystemFont( const Handle(TCollection_HAsciiString)& FontName,
|
||||
const Font_FontAspect FontAspect,
|
||||
const Handle(TCollection_HAsciiString)& FilePath ):
|
||||
MyFontName(FontName),
|
||||
MyFontAspect(FontAspect),
|
||||
MyFaceSize(-1),
|
||||
MyFilePath(FilePath),
|
||||
MyVerification(Standard_True)
|
||||
// =======================================================================
|
||||
// function : SetFontPath
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void Font_SystemFont::SetFontPath (Font_FontAspect theAspect,
|
||||
const TCollection_AsciiString& thePath)
|
||||
{
|
||||
|
||||
if (theAspect == Font_FontAspect_UNDEFINED) { throw Standard_ProgramError ("Font_SystemFont::SetFontPath() called with UNDEFINED aspect"); }
|
||||
myFilePaths[theAspect] = thePath;
|
||||
}
|
||||
|
||||
Font_SystemFont::Font_SystemFont (const Handle(TCollection_HAsciiString)& theXLFD,
|
||||
const Handle(TCollection_HAsciiString)& theFilePath) :
|
||||
MyFontAspect(Font_FA_Regular),
|
||||
MyFaceSize(-1),
|
||||
MyFilePath(theFilePath)
|
||||
// =======================================================================
|
||||
// function : IsEqual
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean Font_SystemFont::IsEqual (const Handle(Font_SystemFont)& theOtherFont) const
|
||||
{
|
||||
MyVerification = Standard_True;
|
||||
if (theXLFD.IsNull())
|
||||
return theOtherFont.get() == this
|
||||
|| myFontKey.IsEqual (theOtherFont->myFontKey);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : ToString
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
TCollection_AsciiString Font_SystemFont::ToString() const
|
||||
{
|
||||
TCollection_AsciiString aDesc;
|
||||
aDesc += TCollection_AsciiString() + "'" + myFontName + "'";
|
||||
|
||||
bool isFirstAspect = true;
|
||||
aDesc += " [aspects: ";
|
||||
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
|
||||
{
|
||||
MyVerification = Standard_False; // empty font description handler
|
||||
}
|
||||
if (theXLFD->IsEmpty())
|
||||
if (!HasFontAspect ((Font_FontAspect )anAspectIter))
|
||||
{
|
||||
MyVerification = Standard_False; // empty font description
|
||||
continue;
|
||||
}
|
||||
|
||||
if (MyVerification)
|
||||
if (!isFirstAspect)
|
||||
{
|
||||
MyFontName = theXLFD->Token ("-", 2);
|
||||
TCollection_AsciiString aXLFD (theXLFD->ToCString());
|
||||
|
||||
// Getting font size for fixed size fonts
|
||||
if (aXLFD.Search ("-0-0-0-0-") >= 0)
|
||||
MyFaceSize = -1; // Scalable font
|
||||
aDesc += ",";
|
||||
}
|
||||
else
|
||||
//TODO catch exeption
|
||||
MyFaceSize = aXLFD.Token ("-", 7).IntegerValue();
|
||||
|
||||
// Detect font aspect
|
||||
if (aXLFD.Token ("-", 3).IsEqual ("bold") &&
|
||||
(aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o")))
|
||||
{
|
||||
MyFontAspect = Font_FA_BoldItalic;
|
||||
isFirstAspect = false;
|
||||
}
|
||||
else if (aXLFD.Token ("-", 3).IsEqual ("bold"))
|
||||
aDesc += Font_FontMgr::FontAspectToString ((Font_FontAspect )anAspectIter);
|
||||
}
|
||||
aDesc += "]";
|
||||
|
||||
isFirstAspect = true;
|
||||
aDesc += " [paths: ";
|
||||
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
|
||||
{
|
||||
MyFontAspect = Font_FA_Bold;
|
||||
}
|
||||
else if (aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o"))
|
||||
if (!HasFontAspect ((Font_FontAspect )anAspectIter))
|
||||
{
|
||||
MyFontAspect = Font_FA_Italic;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Boolean Font_SystemFont::IsValid() const{
|
||||
if ( !MyVerification)
|
||||
return Standard_False;
|
||||
|
||||
if ( MyFontAspect == Font_FA_Undefined )
|
||||
return Standard_False;
|
||||
|
||||
if ( MyFontName->IsEmpty() || !MyFontName->IsAscii() )
|
||||
return Standard_False;
|
||||
|
||||
OSD_Path path;
|
||||
return path.IsValid( MyFilePath->String() );
|
||||
}
|
||||
|
||||
Handle(TCollection_HAsciiString) Font_SystemFont::FontPath() const{
|
||||
return MyFilePath;
|
||||
}
|
||||
|
||||
Handle(TCollection_HAsciiString) Font_SystemFont::FontName() const{
|
||||
return MyFontName;
|
||||
}
|
||||
|
||||
Font_FontAspect Font_SystemFont::FontAspect() const{
|
||||
return MyFontAspect;
|
||||
}
|
||||
|
||||
Standard_Integer Font_SystemFont::FontHeight() const {
|
||||
return MyFaceSize;
|
||||
}
|
||||
|
||||
Standard_Boolean Font_SystemFont::IsEqual(const Handle(Font_SystemFont)& theOtherFont) const
|
||||
{
|
||||
if (!MyFontName->IsSameString (theOtherFont->FontName(), Standard_False))
|
||||
if (!isFirstAspect)
|
||||
{
|
||||
return Standard_False;
|
||||
aDesc += ";";
|
||||
}
|
||||
|
||||
if (MyFontAspect != theOtherFont->FontAspect())
|
||||
else
|
||||
{
|
||||
return Standard_False;
|
||||
isFirstAspect = false;
|
||||
}
|
||||
|
||||
if (MyFaceSize != theOtherFont->FontHeight())
|
||||
{
|
||||
return Standard_False;
|
||||
aDesc += FontPath ((Font_FontAspect )anAspectIter);
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
aDesc += "]";
|
||||
return aDesc;
|
||||
}
|
||||
|
@@ -16,85 +16,123 @@
|
||||
#ifndef _Font_SystemFont_HeaderFile
|
||||
#define _Font_SystemFont_HeaderFile
|
||||
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include <Font_FontAspect.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
class TCollection_HAsciiString;
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
|
||||
class Font_SystemFont;
|
||||
DEFINE_STANDARD_HANDLE(Font_SystemFont, Standard_Transient)
|
||||
|
||||
//! Structure for store of Font System Information
|
||||
//! This class stores information about the font, which is merely a file path and cached metadata about the font.
|
||||
class Font_SystemFont : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Creates a new font object.
|
||||
Standard_EXPORT Font_SystemFont (const TCollection_AsciiString& theFontName);
|
||||
|
||||
//! Returns font family name (lower-cased).
|
||||
const TCollection_AsciiString& FontKey() const { return myFontKey; }
|
||||
|
||||
//! Returns font family name.
|
||||
const TCollection_AsciiString& FontName() const { return myFontName; }
|
||||
|
||||
//! Returns font file path.
|
||||
const TCollection_AsciiString& FontPath (Font_FontAspect theAspect) const
|
||||
{
|
||||
return myFilePaths[theAspect != Font_FontAspect_UNDEFINED ? theAspect : Font_FontAspect_Regular];
|
||||
}
|
||||
|
||||
//! Sets font file path for specific aspect.
|
||||
Standard_EXPORT void SetFontPath (Font_FontAspect theAspect,
|
||||
const TCollection_AsciiString& thePath);
|
||||
|
||||
//! Returns TRUE if dedicated file for specified font aspect has been defined.
|
||||
bool HasFontAspect (Font_FontAspect theAspect) const
|
||||
{
|
||||
return !myFilePaths[theAspect != Font_FontAspect_UNDEFINED ? theAspect : Font_FontAspect_Regular].IsEmpty();
|
||||
}
|
||||
|
||||
//! Returns any defined font file path.
|
||||
const TCollection_AsciiString& FontPathAny (Font_FontAspect theAspect,
|
||||
bool& theToSynthesizeItalic) const
|
||||
{
|
||||
const TCollection_AsciiString& aPath = myFilePaths[theAspect != Font_FontAspect_UNDEFINED ? theAspect : Font_FontAspect_Regular];
|
||||
if (!aPath.IsEmpty())
|
||||
{
|
||||
return aPath;
|
||||
}
|
||||
|
||||
if (theAspect == Font_FontAspect_Italic
|
||||
|| theAspect == Font_FontAspect_BoldItalic)
|
||||
{
|
||||
if (theAspect == Font_FontAspect_BoldItalic
|
||||
&& !myFilePaths[Font_FontAspect_Bold].IsEmpty())
|
||||
{
|
||||
theToSynthesizeItalic = true;
|
||||
return myFilePaths[Font_FontAspect_Bold];
|
||||
}
|
||||
else if (!myFilePaths[Font_FontAspect_Regular].IsEmpty())
|
||||
{
|
||||
theToSynthesizeItalic = true;
|
||||
return myFilePaths[Font_FontAspect_Regular];
|
||||
}
|
||||
}
|
||||
|
||||
if (!myFilePaths[Font_FontAspect_Regular].IsEmpty())
|
||||
{
|
||||
return myFilePaths[Font_FontAspect_Regular];
|
||||
}
|
||||
|
||||
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
|
||||
{
|
||||
if (!myFilePaths[anAspectIter].IsEmpty())
|
||||
{
|
||||
return myFilePaths[anAspectIter];
|
||||
}
|
||||
}
|
||||
return myFilePaths[Font_FontAspect_Regular];
|
||||
}
|
||||
|
||||
//! Return true if the FontName, FontAspect and FontSize are the same.
|
||||
Standard_EXPORT Standard_Boolean IsEqual (const Handle(Font_SystemFont)& theOtherFont) const;
|
||||
|
||||
//! Return TRUE if this is single-stroke (one-line) font, FALSE by default.
|
||||
//! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software.
|
||||
Standard_Boolean IsSingleStrokeFont() const { return myIsSingleLine; }
|
||||
|
||||
//! Set if this font should be rendered as single-stroke (one-line).
|
||||
void SetSingleStrokeFont (Standard_Boolean theIsSingleLine) { myIsSingleLine = theIsSingleLine; }
|
||||
|
||||
//! Format font description.
|
||||
Standard_EXPORT TCollection_AsciiString ToString() const;
|
||||
|
||||
public:
|
||||
|
||||
//! Hash value, for Map interface.
|
||||
//! Based on Font Family, so that the whole family with different aspects can be found within the same bucket.
|
||||
static Standard_Integer HashCode (const Handle(Font_SystemFont)& theFont,
|
||||
const Standard_Integer theUpper)
|
||||
{
|
||||
return ::HashCode (theFont->FontKey(), theUpper);
|
||||
}
|
||||
|
||||
//! Creates empty font object
|
||||
Standard_EXPORT Font_SystemFont();
|
||||
|
||||
//! Creates Font object initialized with <FontName> as name
|
||||
//! <FontAspect>.... TODO
|
||||
Standard_EXPORT Font_SystemFont(const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Handle(TCollection_HAsciiString)& theFilePath);
|
||||
|
||||
//! Creates Font object and initialize class fields with
|
||||
//! values taken from XLFD (X Logical Font Description)
|
||||
Standard_EXPORT Font_SystemFont(const Handle(TCollection_HAsciiString)& theXLFD, const Handle(TCollection_HAsciiString)& theFilePath);
|
||||
|
||||
//! Returns font family name
|
||||
Standard_EXPORT Handle(TCollection_HAsciiString) FontName() const;
|
||||
|
||||
//! Returns font file path
|
||||
//! Level: Public
|
||||
Standard_EXPORT Handle(TCollection_HAsciiString) FontPath() const;
|
||||
|
||||
//! Returns font aspect
|
||||
//! Level: Public
|
||||
Standard_EXPORT Font_FontAspect FontAspect() const;
|
||||
|
||||
//! Returns font height
|
||||
//! If returned value is equal -1 it means that font is resizable
|
||||
//! Level: Public
|
||||
Standard_EXPORT Standard_Integer FontHeight() const;
|
||||
|
||||
Standard_EXPORT Standard_Boolean IsValid() const;
|
||||
|
||||
//! Return true if the FontName, FontAspect and FontSize are the same.
|
||||
//! Level: Public
|
||||
Standard_EXPORT Standard_Boolean IsEqual (const Handle(Font_SystemFont)& theOtherFont) const;
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Font_SystemFont,Standard_Transient)
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
//! Matching two instances, for Map interface.
|
||||
static bool IsEqual (const Handle(Font_SystemFont)& theFont1,
|
||||
const Handle(Font_SystemFont)& theFont2)
|
||||
{
|
||||
return theFont1->IsEqual (theFont2);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Handle(TCollection_HAsciiString) MyFontName;
|
||||
Font_FontAspect MyFontAspect;
|
||||
Standard_Integer MyFaceSize;
|
||||
Handle(TCollection_HAsciiString) MyFilePath;
|
||||
Standard_Boolean MyVerification;
|
||||
|
||||
TCollection_AsciiString myFilePaths[Font_FontAspect_NB]; //!< paths to the font file
|
||||
TCollection_AsciiString myFontKey; //!< font family name, lower cased
|
||||
TCollection_AsciiString myFontName; //!< font family name
|
||||
Standard_Boolean myIsSingleLine; //!< single stroke font flag, FALSE by default
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_HANDLE(Font_SystemFont, Standard_Transient)
|
||||
|
||||
#endif // _Font_SystemFont_HeaderFile
|
||||
|
28
src/Font/Font_UnicodeSubset.hxx
Normal file
28
src/Font/Font_UnicodeSubset.hxx
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2019 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 _Font_UnicodeSubset_HeaderFile
|
||||
#define _Font_UnicodeSubset_HeaderFile
|
||||
|
||||
//! Enumeration defining Unicode subsets.
|
||||
enum Font_UnicodeSubset
|
||||
{
|
||||
Font_UnicodeSubset_Western, //!< western letters
|
||||
Font_UnicodeSubset_Korean, //!< modern Korean letters
|
||||
Font_UnicodeSubset_CJK, //!< Chinese characters (Chinese, Japanese, Korean and Vietnam)
|
||||
Font_UnicodeSubset_Arabic, //!< Arabic characters
|
||||
};
|
||||
|
||||
enum { Font_UnicodeSubset_NB = Font_UnicodeSubset_Arabic };
|
||||
|
||||
#endif // _Font_UnicodeSubset_HeaderFile
|
@@ -191,7 +191,7 @@ pararg2(1,aNbSolMAX)
|
||||
Geom2dInt_TheIntConicCurveOfGInter Intp(Line,D1,C2,D2,Tol,Tol);
|
||||
if (Intp.IsDone()) {
|
||||
if (!Intp.IsEmpty()) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < cirsol.Length() ; i++) {
|
||||
NbrSol++;
|
||||
gp_Pnt2d Center(Intp.Point(i).Value());
|
||||
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
|
||||
@@ -375,7 +375,7 @@ pararg2(1,aNbSolMAX)
|
||||
Intp.Perform(Circ,D1,C2,D2,Tol,Tol);
|
||||
if (Intp.IsDone()) {
|
||||
if (!Intp.IsEmpty()) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < cirsol.Length() ; i++) {
|
||||
NbrSol++;
|
||||
gp_Pnt2d Center(Intp.Point(i).Value());
|
||||
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
|
||||
@@ -507,7 +507,7 @@ pararg2(1,aNbSolMAX)
|
||||
Intp.Perform(Circ,D1,Cu2,D2,Tol,Tol);
|
||||
if (Intp.IsDone()) {
|
||||
if (!Intp.IsEmpty()) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < cirsol.Length(); i++) {
|
||||
NbrSol++;
|
||||
gp_Pnt2d Center(Intp.Point(i).Value());
|
||||
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
|
||||
@@ -853,7 +853,7 @@ pararg2(1,aNbSolMAX)
|
||||
if (!Intp.IsEmpty()) {
|
||||
const Standard_Real aSQApproxTol = Precision::Approximation() *
|
||||
Precision::Approximation();
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++)
|
||||
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < cirsol.Length() ; i++)
|
||||
{
|
||||
Standard_Real aU0 = Intp.Point(i).ParamOnFirst();
|
||||
Standard_Real aV0 = Intp.Point(i).ParamOnSecond();
|
||||
|
@@ -365,7 +365,7 @@ static Standard_Integer xdistcs(Draw_Interpretor& di, Standard_Integer n, const
|
||||
// report error or warning if distance is greater than tolerance
|
||||
if (aD > anErrTol)
|
||||
{
|
||||
di << "Error :";
|
||||
di << "Error in " << a[1] << ":";
|
||||
}
|
||||
else if (aD > aWarnTol)
|
||||
{
|
||||
|
@@ -24,7 +24,9 @@ IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_AspectLine3d, Standard_Transient)
|
||||
Graphic3d_AspectLine3d::Graphic3d_AspectLine3d()
|
||||
: myColor (Quantity_NOC_YELLOW),
|
||||
myType (Aspect_TOL_SOLID),
|
||||
myWidth (1.0f)
|
||||
myWidth (1.0f),
|
||||
myLineFactor (1),
|
||||
myLinePattern (0xFFFF)
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -38,7 +40,9 @@ Graphic3d_AspectLine3d::Graphic3d_AspectLine3d (const Quantity_Color& theColor
|
||||
const Standard_Real theWidth)
|
||||
: myColor (theColor),
|
||||
myType (theType),
|
||||
myWidth ((float )theWidth)
|
||||
myWidth ((float )theWidth),
|
||||
myLineFactor (1),
|
||||
myLinePattern (DefaultLinePatternForType (theType))
|
||||
{
|
||||
if (myWidth <= 0.0f)
|
||||
{
|
||||
|
@@ -61,7 +61,64 @@ public:
|
||||
Aspect_TypeOfLine Type() const { return myType; }
|
||||
|
||||
//! Modifies the type of line.
|
||||
void SetType (const Aspect_TypeOfLine theType) { myType = theType; }
|
||||
void SetType (const Aspect_TypeOfLine theType)
|
||||
{
|
||||
myType = theType;
|
||||
myLinePattern = DefaultLinePatternForType (theType);
|
||||
}
|
||||
|
||||
//! Return custom stipple line pattern; 0xFFFF by default.
|
||||
uint16_t LinePattern() const { return myLinePattern; }
|
||||
|
||||
//! Modifies the stipple line pattern, and changes line type to Aspect_TOL_USERDEFINED for non-standard pattern.
|
||||
void SetLinePattern (uint16_t thePattern)
|
||||
{
|
||||
myType = DefaultLineTypeForPattern (thePattern);
|
||||
myLinePattern = thePattern;
|
||||
}
|
||||
|
||||
//! Return stipple line pattern for line type.
|
||||
static uint16_t DefaultLinePatternForType (Aspect_TypeOfLine theType)
|
||||
{
|
||||
switch (theType)
|
||||
{
|
||||
case Aspect_TOL_DASH: return 0xFFC0;
|
||||
case Aspect_TOL_DOT: return 0xCCCC;
|
||||
case Aspect_TOL_DOTDASH: return 0xFF18;
|
||||
case Aspect_TOL_EMPTY: return 0x0000;
|
||||
case Aspect_TOL_SOLID: return 0xFFFF;
|
||||
case Aspect_TOL_USERDEFINED: return 0xFF24;
|
||||
}
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
//! Return line type for stipple line pattern.
|
||||
static Aspect_TypeOfLine DefaultLineTypeForPattern (uint16_t thePattern)
|
||||
{
|
||||
switch (thePattern)
|
||||
{
|
||||
case 0x0000: return Aspect_TOL_EMPTY;
|
||||
case 0xFFC0: return Aspect_TOL_DASH;
|
||||
case 0xCCCC: return Aspect_TOL_DOT;
|
||||
case 0xFF18: return Aspect_TOL_DOTDASH;
|
||||
case 0xFFFF: return Aspect_TOL_SOLID;
|
||||
case 0xFF24: return Aspect_TOL_USERDEFINED;
|
||||
}
|
||||
return Aspect_TOL_USERDEFINED;
|
||||
}
|
||||
|
||||
//! Return a multiplier for each bit in the line stipple pattern within [1, 256] range; 1 by default.
|
||||
uint16_t LineStippleFactor() const { return myLineFactor; }
|
||||
|
||||
//! Set a multiplier for each bit in the line stipple pattern.
|
||||
void SetLineStippleFactor (uint16_t theFactor)
|
||||
{
|
||||
if (theFactor == 0 || theFactor > 256)
|
||||
{
|
||||
throw Standard_OutOfRange ("Graphic3d_Aspects::SetLineStippleFactor(), bad factor value");
|
||||
}
|
||||
myLineFactor = theFactor;
|
||||
}
|
||||
|
||||
//! Return line width.
|
||||
Standard_ShortReal Width() const { return myWidth; }
|
||||
@@ -97,6 +154,8 @@ public:
|
||||
|
||||
return myProgram == theOther.myProgram
|
||||
&& myType == theOther.myType
|
||||
&& myLineFactor == theOther.myLineFactor
|
||||
&& myLinePattern == theOther.myLinePattern
|
||||
&& myColor == theOther.myColor
|
||||
&& myWidth == theOther.myWidth;
|
||||
}
|
||||
@@ -120,6 +179,8 @@ protected:
|
||||
Quantity_ColorRGBA myColor;
|
||||
Aspect_TypeOfLine myType;
|
||||
Standard_ShortReal myWidth;
|
||||
uint16_t myLineFactor;
|
||||
uint16_t myLinePattern;
|
||||
|
||||
};
|
||||
|
||||
|
@@ -16,7 +16,8 @@
|
||||
#ifndef _Graphic3d_RenderingParams_HeaderFile
|
||||
#define _Graphic3d_RenderingParams_HeaderFile
|
||||
|
||||
#include <Graphic3d_Mat4.hxx>
|
||||
#include <Graphic3d_AspectText3d.hxx>
|
||||
#include <Graphic3d_TransformPers.hxx>
|
||||
#include <Graphic3d_RenderTransparentMethod.hxx>
|
||||
#include <Graphic3d_RenderingMode.hxx>
|
||||
#include <Graphic3d_StereoMode.hxx>
|
||||
@@ -44,6 +45,31 @@ public:
|
||||
Anaglyph_UserDefined //!< use externally specified matrices
|
||||
};
|
||||
|
||||
//! Statistics display flags.
|
||||
enum PerfCounters
|
||||
{
|
||||
PerfCounters_NONE = 0x000, //!< no stats
|
||||
PerfCounters_FrameRate = 0x001, //!< Frame Rate
|
||||
PerfCounters_CPU = 0x002, //!< CPU utilization
|
||||
PerfCounters_Layers = 0x004, //!< count layers (groups of structures)
|
||||
PerfCounters_Structures = 0x008, //!< count low-level Structures (normal unhighlighted Presentable Object is usually represented by 1 Structure)
|
||||
//
|
||||
PerfCounters_Groups = 0x010, //!< count primitive Groups (1 Structure holds 1 or more primitive Group)
|
||||
PerfCounters_GroupArrays = 0x020, //!< count Arrays within Primitive Groups (optimal primitive Group holds 1 Array)
|
||||
//
|
||||
PerfCounters_Triangles = 0x040, //!< count Triangles
|
||||
PerfCounters_Points = 0x080, //!< count Points
|
||||
//
|
||||
PerfCounters_EstimMem = 0x100, //!< estimated GPU memory usage
|
||||
//! show basic statistics
|
||||
PerfCounters_Basic = PerfCounters_FrameRate | PerfCounters_CPU | PerfCounters_Layers | PerfCounters_Structures,
|
||||
//! extended (verbose) statistics
|
||||
PerfCounters_Extended = PerfCounters_Basic
|
||||
| PerfCounters_Groups | PerfCounters_GroupArrays
|
||||
| PerfCounters_Triangles | PerfCounters_Points
|
||||
| PerfCounters_EstimMem,
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
//! Creates default rendering parameters.
|
||||
@@ -53,6 +79,7 @@ public:
|
||||
OitDepthFactor (0.0f),
|
||||
NbMsaaSamples (0),
|
||||
RenderResolutionScale (1.0f),
|
||||
ToEnableDepthPrepass (Standard_False),
|
||||
// ray tracing parameters
|
||||
IsGlobalIlluminationEnabled (Standard_False),
|
||||
RaytracingDepth (THE_DEFAULT_DEPTH),
|
||||
@@ -77,7 +104,14 @@ public:
|
||||
StereoMode (Graphic3d_StereoMode_QuadBuffer),
|
||||
AnaglyphFilter (Anaglyph_RedCyan_Optimized),
|
||||
ToReverseStereo (Standard_False),
|
||||
|
||||
//
|
||||
StatsPosition (new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i (20, 20))),
|
||||
StatsTextAspect (new Graphic3d_AspectText3d()),
|
||||
StatsUpdateInterval (1.0),
|
||||
StatsTextHeight (16),
|
||||
CollectedStats (PerfCounters_Basic),
|
||||
ToShowStats (Standard_False),
|
||||
//
|
||||
Resolution (THE_DEFAULT_RESOLUTION)
|
||||
{
|
||||
const Graphic3d_Vec4 aZero (0.0f, 0.0f, 0.0f, 0.0f);
|
||||
@@ -89,6 +123,13 @@ public:
|
||||
AnaglyphRight.SetRow (1, Graphic3d_Vec4 (0.0f, 1.0f, 0.0f, 0.0f));
|
||||
AnaglyphRight.SetRow (2, Graphic3d_Vec4 (0.0f, 0.0f, 1.0f, 0.0f));
|
||||
AnaglyphRight.SetRow (3, aZero);
|
||||
|
||||
StatsTextAspect->SetColor (Quantity_NOC_WHITE);
|
||||
StatsTextAspect->SetColorSubTitle (Quantity_NOC_BLACK);
|
||||
StatsTextAspect->SetFont (Font_NOF_ASCII_MONO);
|
||||
///StatsTextAspect->SetDisplayType (Aspect_TODT_SHADOW);
|
||||
StatsTextAspect->SetTextZoomable (Standard_False);
|
||||
StatsTextAspect->SetTextFontAspect (Font_FA_Regular);
|
||||
}
|
||||
|
||||
//! Returns resolution ratio.
|
||||
@@ -105,6 +146,7 @@ public:
|
||||
Standard_Integer NbMsaaSamples; //!< number of MSAA samples (should be within 0..GL_MAX_SAMPLES, power-of-two number), 0 by default
|
||||
Standard_ShortReal RenderResolutionScale; //!< rendering resolution scale factor, 1 by default;
|
||||
//! incompatible with MSAA (e.g. NbMsaaSamples should be set to 0)
|
||||
Standard_Boolean ToEnableDepthPrepass; //!< enables/disables depth pre-pass, False by default
|
||||
|
||||
Standard_Boolean IsGlobalIlluminationEnabled; //!< enables/disables global illumination effects (path tracing)
|
||||
Standard_Integer SamplesPerPixel; //!< number of samples per pixel (SPP)
|
||||
@@ -134,6 +176,20 @@ public:
|
||||
Graphic3d_Mat4 AnaglyphRight; //!< right anaglyph filter (in normalized colorspace), Color = AnaglyphRight * theColorRight + AnaglyphLeft * theColorLeft;
|
||||
Standard_Boolean ToReverseStereo; //!< flag to reverse stereo pair, FALSE by default
|
||||
|
||||
Handle(Graphic3d_TransformPers) StatsPosition; //!< location of stats, upper-left position by default
|
||||
Handle(Graphic3d_AspectText3d) StatsTextAspect; //!< stats text aspect
|
||||
Standard_ShortReal StatsUpdateInterval; //!< time interval between stats updates in seconds, 1.0 second by default;
|
||||
//! too often updates might impact performance and will smear text within widgets
|
||||
//! (especially framerate, which is better averaging);
|
||||
//! 0.0 interval will force updating on each frame
|
||||
Standard_Integer StatsTextHeight; //!< stats text size; 16 by default
|
||||
PerfCounters CollectedStats; //!< performance counters to collect, PerfCounters_Basic by default;
|
||||
//! too verbose options might impact rendering performance,
|
||||
//! because some counters might lack caching optimization (and will require expensive iteration through all data structures)
|
||||
Standard_Boolean ToShowStats; //!< display performance statistics, FALSE by default;
|
||||
//! note that counters specified within CollectedStats will be updated nevertheless
|
||||
//! of visibility of widget managed by ToShowStats flag (e.g. stats can be retrieved by application for displaying using other methods)
|
||||
|
||||
unsigned int Resolution; //!< Pixels density (PPI), defines scaling factor for parameters like text size
|
||||
//! (when defined in screen-space units rather than in 3D) to be properly displayed
|
||||
//! on device (screen / printer). 72 is default value.
|
||||
|
@@ -49,6 +49,11 @@ public:
|
||||
//! Returns unique ID used to manage resource in graphic driver.
|
||||
const TCollection_AsciiString& GetId() const { return myID; }
|
||||
|
||||
//! Sets unique ID used to manage resource in graphic driver.
|
||||
//! WARNING! Graphic3d_ShaderProgram constructor generates a unique id for proper resource management;
|
||||
//! however if application overrides it, it is responsibility of application to avoid name collisions.
|
||||
void SetId (const TCollection_AsciiString& theId) { myID = theId; }
|
||||
|
||||
//! Returns GLSL header (version code and extensions).
|
||||
const TCollection_AsciiString& Header() const { return myHeader; }
|
||||
|
||||
|
@@ -33,11 +33,14 @@ struct Graphic3d_ZLayerSettings
|
||||
|
||||
//! Default settings.
|
||||
Graphic3d_ZLayerSettings()
|
||||
: myIsImmediate (Standard_False),
|
||||
: myCullingDistance (Precision::Infinite()),
|
||||
myCullingSize (Precision::Infinite()),
|
||||
myIsImmediate (Standard_False),
|
||||
myUseEnvironmentTexture (Standard_True),
|
||||
myToEnableDepthTest (Standard_True),
|
||||
myToEnableDepthWrite(Standard_True),
|
||||
myToClearDepth (Standard_True) {}
|
||||
myToClearDepth (Standard_True),
|
||||
myToRenderInDepthPrepass (Standard_True) {}
|
||||
|
||||
//! Return user-provided name.
|
||||
const TCollection_AsciiString& Name() const { return myName; }
|
||||
@@ -62,6 +65,30 @@ struct Graphic3d_ZLayerSettings
|
||||
}
|
||||
}
|
||||
|
||||
//! Return TRUE, if culling of distant objects (distance culling) should be performed; FALSE by default.
|
||||
//! @sa CullingDistance()
|
||||
Standard_Boolean HasCullingDistance() const { return !Precision::IsInfinite (myCullingDistance) && myCullingDistance > 0.0; }
|
||||
|
||||
//! Return the distance to discard drawing of distant objects (distance from camera Eye point); by default it is Infinite (distance culling is disabled).
|
||||
//! Since camera eye definition has no strong meaning within orthographic projection, option is considered only within perspective projection.
|
||||
//! Note also that this option has effect only when frustum culling is enabled.
|
||||
Standard_Real CullingDistance() const { return myCullingDistance; }
|
||||
|
||||
//! Set the distance to discard drawing objects.
|
||||
void SetCullingDistance (Standard_Real theDistance) { myCullingDistance = theDistance; }
|
||||
|
||||
//! Return TRUE, if culling of small objects (size culling) should be performed; FALSE by default.
|
||||
//! @sa CullingSize()
|
||||
Standard_Boolean HasCullingSize() const { return !Precision::IsInfinite (myCullingSize) && myCullingSize > 0.0; }
|
||||
|
||||
//! Return the size to discard drawing of small objects; by default it is Infinite (size culling is disabled).
|
||||
//! Current implementation checks the length of projected diagonal of bounding box in pixels for discarding.
|
||||
//! Note that this option has effect only when frustum culling is enabled.
|
||||
Standard_Real CullingSize() const { return myCullingSize; }
|
||||
|
||||
//! Set the distance to discard drawing objects.
|
||||
void SetCullingSize (Standard_Real theSize) { myCullingSize = theSize; }
|
||||
|
||||
//! Return true if this layer should be drawn after all normal (non-immediate) layers.
|
||||
Standard_Boolean IsImmediate() const { return myIsImmediate; }
|
||||
|
||||
@@ -92,6 +119,12 @@ struct Graphic3d_ZLayerSettings
|
||||
//! Set if depth values should be cleared before drawing the layer.
|
||||
void SetClearDepth (const Standard_Boolean theValue) { myToClearDepth = theValue; }
|
||||
|
||||
//! Return TRUE if layer should be rendered within depth pre-pass; TRUE by default.
|
||||
Standard_Boolean ToRenderInDepthPrepass() const { return myToRenderInDepthPrepass; }
|
||||
|
||||
//! Set if layer should be rendered within depth pre-pass.
|
||||
void SetRenderInDepthPrepass (Standard_Boolean theToRender) { myToRenderInDepthPrepass = theToRender; }
|
||||
|
||||
//! Return glPolygonOffset() arguments.
|
||||
const Graphic3d_PolygonOffset& PolygonOffset() const { return myPolygonOffset; }
|
||||
|
||||
@@ -162,12 +195,15 @@ protected:
|
||||
TCollection_AsciiString myName; //!< user-provided name
|
||||
Handle(Geom_Transformation) myOriginTrsf; //!< transformation to the origin
|
||||
gp_XYZ myOrigin; //!< the origin of all objects within the layer
|
||||
Standard_Real myCullingDistance; //!< distance to discard objects
|
||||
Standard_Real myCullingSize; //!< size to discard objects
|
||||
Graphic3d_PolygonOffset myPolygonOffset; //!< glPolygonOffset() arguments
|
||||
Standard_Boolean myIsImmediate; //!< immediate layer will be drawn after all normal layers
|
||||
Standard_Boolean myUseEnvironmentTexture; //!< flag to allow/prevent environment texture mapping usage for specific layer
|
||||
Standard_Boolean myToEnableDepthTest; //!< option to enable depth test
|
||||
Standard_Boolean myToEnableDepthWrite; //!< option to enable write depth values
|
||||
Standard_Boolean myToClearDepth; //!< option to clear depth values before drawing the layer
|
||||
Standard_Boolean myToRenderInDepthPrepass;//!< option to render layer within depth pre-pass
|
||||
|
||||
};
|
||||
|
||||
|
@@ -42,7 +42,7 @@ class HLRAlgo_Coincidence
|
||||
public:
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
Standard_EXPORT HLRAlgo_Coincidence() :
|
||||
HLRAlgo_Coincidence() :
|
||||
myFE(0),
|
||||
myParam(0.),
|
||||
myStBef(TopAbs_IN),
|
||||
|
@@ -382,8 +382,8 @@ void HLRAlgo_PolyData::hideByOneTriangle (const HLRAlgo_BiPoint::PointsT& thePoi
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (HLRAlgo_PolyData_ERROR) {
|
||||
cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
|
||||
cout << " ( more than 2 points )." << endl;
|
||||
std::cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << std::endl;
|
||||
std::cout << " ( more than 2 points )." << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -470,7 +470,7 @@ void HLRAlgo_PolyData::hideByOneTriangle (const HLRAlgo_BiPoint::PointsT& thePoi
|
||||
if (d2 < 0) ad2 = -d2;
|
||||
pp = ad1 / ( ad1 + ad2 );
|
||||
if (TrFlags & HLRAlgo_PolyMask_EMskGrALin2)
|
||||
pdp = (thePoints.PntP1.X() + (thePoints.Pnt2.X() - thePoints.PntP1.X()) * pp - theTriangle.V2.X()) / aD.X();
|
||||
pdp = (thePoints.PntP1.X() + (thePoints.PntP2.X() - thePoints.PntP1.X()) * pp - theTriangle.V2.X()) / aD.X();
|
||||
else
|
||||
pdp = (thePoints.PntP1.Y() + (thePoints.PntP2.Y() - thePoints.PntP1.Y()) * pp - theTriangle.V2.Y()) / aD.Y();
|
||||
Standard_Boolean OutSideP = Standard_False;
|
||||
@@ -524,8 +524,8 @@ void HLRAlgo_PolyData::hideByOneTriangle (const HLRAlgo_BiPoint::PointsT& thePoi
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (HLRAlgo_PolyData_ERROR) {
|
||||
cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
|
||||
cout << " ( more than 2 points )." << endl;
|
||||
std::cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << std::endl;
|
||||
std::cout << " ( more than 2 points )." << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -666,8 +666,8 @@ void HLRAlgo_PolyData::hideByOneTriangle (const HLRAlgo_BiPoint::PointsT& thePoi
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (HLRAlgo_PolyData_ERROR) {
|
||||
cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << endl;
|
||||
cout << " ( more than 2 points )." << endl;
|
||||
std::cout << " error : HLRAlgo_PolyData::HideByOneTriangle " << std::endl;
|
||||
std::cout << " ( more than 2 points )." << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -326,7 +326,7 @@ HLRAlgo_PolyInternalData::AddNode (
|
||||
Nod3RValues.Normal = gp_XYZ(1., 0., 0.);
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_ERROR)
|
||||
cout << "HLRAlgo_PolyInternalData::AddNode" << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::AddNode" << std::endl;
|
||||
#endif
|
||||
}
|
||||
return ip3;
|
||||
@@ -415,8 +415,8 @@ HLRAlgo_PolyInternalData::UpdateLinks (const Standard_Integer ip1,
|
||||
myNbPISeg--;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_ERROR) {
|
||||
cout << "HLRAlgo_PolyInternalData::UpdateLinks : segment error";
|
||||
cout << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::UpdateLinks : segment error";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -520,8 +520,8 @@ HLRAlgo_PolyInternalData::UpdateLinks (const Standard_Integer ip1,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (HLRAlgo_PolyInternalData_ERROR) {
|
||||
cout << "HLRAlgo_PolyInternalData::UpdateLinks : triangle error ";
|
||||
cout << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::UpdateLinks : triangle error ";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -640,33 +640,33 @@ void HLRAlgo_PolyInternalData::Dump () const
|
||||
const Handle(HLRAlgo_PolyInternalNode)* pi = &PINod->ChangeValue(i);
|
||||
HLRAlgo_PolyInternalNode::NodeIndices& aNodIndices1 = (*pi)->Indices();
|
||||
HLRAlgo_PolyInternalNode::NodeData& Nod1RValues = (*pi)->Data();
|
||||
cout << "Node " << setw(6) << i << " : ";
|
||||
cout << setw(6) << aNodIndices1.NdSg;
|
||||
cout << setw(20)<< Nod1RValues.Point.X();
|
||||
cout << setw(20)<< Nod1RValues.Point.Y();
|
||||
cout << setw(20)<< Nod1RValues.Point.Z();
|
||||
cout << endl;
|
||||
std::cout << "Node " << std::setw(6) << i << " : ";
|
||||
std::cout << std::setw(6) << aNodIndices1.NdSg;
|
||||
std::cout << std::setw(20)<< Nod1RValues.Point.X();
|
||||
std::cout << std::setw(20)<< Nod1RValues.Point.Y();
|
||||
std::cout << std::setw(20)<< Nod1RValues.Point.Z();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
for (i = 1; i <= myNbPISeg; i++) {
|
||||
HLRAlgo_PolyInternalSegment* aSegIndices = &PISeg->ChangeValue(i);
|
||||
cout << "Segment " << setw(6) << i << " : ";
|
||||
cout << setw(6) << aSegIndices->LstSg1;
|
||||
cout << setw(6) << aSegIndices->LstSg2;
|
||||
cout << setw(6) << aSegIndices->NxtSg1;
|
||||
cout << setw(6) << aSegIndices->NxtSg2;
|
||||
cout << setw(6) << aSegIndices->Conex1;
|
||||
cout << setw(6) << aSegIndices->Conex2;
|
||||
cout << endl;
|
||||
std::cout << "Segment " << std::setw(6) << i << " : ";
|
||||
std::cout << std::setw(6) << aSegIndices->LstSg1;
|
||||
std::cout << std::setw(6) << aSegIndices->LstSg2;
|
||||
std::cout << std::setw(6) << aSegIndices->NxtSg1;
|
||||
std::cout << std::setw(6) << aSegIndices->NxtSg2;
|
||||
std::cout << std::setw(6) << aSegIndices->Conex1;
|
||||
std::cout << std::setw(6) << aSegIndices->Conex2;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
for (i = 1; i <= myNbTData; i++) {
|
||||
HLRAlgo_TriangleData& aTriangle = TData->ChangeValue(i);
|
||||
cout << "Triangle " << setw(6) << i << " : ";
|
||||
cout << setw(6) << aTriangle.Node1;
|
||||
cout << setw(6) << aTriangle.Node2;
|
||||
cout << setw(6) << aTriangle.Node3;
|
||||
cout << endl;
|
||||
std::cout << "Triangle " << std::setw(6) << i << " : ";
|
||||
std::cout << std::setw(6) << aTriangle.Node1;
|
||||
std::cout << std::setw(6) << aTriangle.Node2;
|
||||
std::cout << std::setw(6) << aTriangle.Node3;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -681,7 +681,7 @@ void HLRAlgo_PolyInternalData::IncTData(
|
||||
if (myNbTData >= myMxTData) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_TRACE)
|
||||
cout << "HLRAlgo_PolyInternalData::IncTData : " << myMxTData << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::IncTData : " << myMxTData << std::endl;
|
||||
#endif
|
||||
Standard_Integer i,j,k;
|
||||
j = myMxTData;
|
||||
@@ -720,7 +720,7 @@ void HLRAlgo_PolyInternalData::IncPISeg(
|
||||
if (myNbPISeg >= myMxPISeg) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_TRACE)
|
||||
cout << "HLRAlgo_PolyInternalData::IncPISeg : " << myMxPISeg << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::IncPISeg : " << myMxPISeg << std::endl;
|
||||
#endif
|
||||
Standard_Integer i,j,k;
|
||||
j = myMxPISeg;
|
||||
@@ -758,7 +758,7 @@ void HLRAlgo_PolyInternalData::IncPINod(
|
||||
if (myNbPINod >= myMxPINod) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (HLRAlgo_PolyInternalData_TRACE)
|
||||
cout << "HLRAlgo_PolyInternalData::IncPINod : " << myMxPINod << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::IncPINod : " << myMxPINod << std::endl;
|
||||
#endif
|
||||
Standard_Integer i,j,k;
|
||||
j = myMxPINod;
|
||||
|
@@ -86,7 +86,6 @@ HLRBRep_ShapeToHLR.cxx
|
||||
HLRBRep_ShapeToHLR.hxx
|
||||
HLRBRep_SLProps.hxx
|
||||
HLRBRep_SLProps_0.cxx
|
||||
HLRBRep_SLPropsATool.cxx
|
||||
HLRBRep_SLPropsATool.hxx
|
||||
HLRBRep_SLPropsATool.lxx
|
||||
HLRBRep_Surface.cxx
|
||||
|
@@ -283,7 +283,7 @@ inline Handle(Geom2d_BezierCurve)
|
||||
HLRBRep_CurveTool::Bezier (const Standard_Address /*C*/)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<" HLRBRep_CurveTool::Bezier : Not Implemented "<<endl;
|
||||
std::cout<<" HLRBRep_CurveTool::Bezier : Not Implemented "<<std::endl;
|
||||
#endif
|
||||
//-- return(((HLRBRep_Curve *)C)->Bezier());
|
||||
return(0);
|
||||
@@ -298,7 +298,7 @@ inline Handle(Geom2d_BSplineCurve)
|
||||
HLRBRep_CurveTool::BSpline (const Standard_Address /*C*/)
|
||||
{
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<" HLRBRep_CurveTool::BSpline : Not Implemented "<<endl;
|
||||
std::cout<<" HLRBRep_CurveTool::BSpline : Not Implemented "<<std::endl;
|
||||
#endif
|
||||
//-- return(((HLRBRep_Curve *)C)->BSpline());
|
||||
return(0);
|
||||
|
@@ -105,7 +105,7 @@ public:
|
||||
//-- ============================================================
|
||||
void SetDim(const Standard_Integer n) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<"\n@#@#@#@#@# SetDim "<<n<<endl;
|
||||
std::cout<<"\n@#@#@#@#@# SetDim "<<n<<std::endl;
|
||||
#endif
|
||||
if(UV)
|
||||
Destroy();
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
~TableauRejection() {
|
||||
//-- cout<<"\n Destructeur TableauRejection"<<endl;
|
||||
//-- std::cout<<"\n Destructeur TableauRejection"<<std::endl;
|
||||
Destroy();
|
||||
}
|
||||
//-- ============================================================
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else
|
||||
cout<<" IndUV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
|
||||
std::cout<<" IndUV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
for(i=0;i<N;i++) {
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
UV[i]=NULL;
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else { cout<<" UV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<endl; }
|
||||
else { std::cout<<" UV ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"<<std::endl; }
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ public:
|
||||
//-- declaration de la Nv ligne de taille : ancienne taille + SIZEUV
|
||||
//--
|
||||
|
||||
//-- cout<<" \n alloc nbUV["<<i0<<"]="<<nbUV[i0];
|
||||
//-- std::cout<<" \n alloc nbUV["<<i0<<"]="<<nbUV[i0];
|
||||
|
||||
Standard_Real *NvLigneUV = (Standard_Real *) malloc((nbUV[i0]+SIZEUV)*sizeof(Standard_Real));
|
||||
Standard_Integer *NvLigneInd = (Standard_Integer *)malloc((nbUV[i0]+SIZEUV)*sizeof(Standard_Integer));
|
||||
@@ -280,7 +280,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
void ResetTabBit(const Standard_Integer nbedgs) {
|
||||
//-- cout<<"\n ResetTabBit"<<endl;
|
||||
//-- std::cout<<"\n ResetTabBit"<<std::endl;
|
||||
if(TabBit) {
|
||||
for(Standard_Integer i=0;i<nbedgs;i++) {
|
||||
if(TabBit[i]) {
|
||||
@@ -295,7 +295,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
void InitTabBit(const Standard_Integer nbedgs) {
|
||||
//-- cout<<"\n InitTabBit"<<endl;
|
||||
//-- std::cout<<"\n InitTabBit"<<std::endl;
|
||||
if(TabBit && nTabBit) {
|
||||
ResetTabBit(nTabBit);
|
||||
}
|
||||
@@ -312,7 +312,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
void SetNoIntersection(Standard_Integer i0,Standard_Integer i1) {
|
||||
// cout<<" SetNoIntersection : "<<i0<<" "<<i1<<endl;
|
||||
// std::cout<<" SetNoIntersection : "<<i0<<" "<<i1<<std::endl;
|
||||
i0--;
|
||||
i1--;
|
||||
if(i0>i1) {
|
||||
@@ -324,7 +324,7 @@ public:
|
||||
}
|
||||
//-- ============================================================
|
||||
Standard_Boolean NoIntersection(Standard_Integer i0,Standard_Integer i1) {
|
||||
// cout<<" ??NoIntersection : "<<i0<<" "<<i1<<" ";
|
||||
// std::cout<<" ??NoIntersection : "<<i0<<" "<<i1<<" ";
|
||||
i0--;
|
||||
i1--;
|
||||
if(i0>i1) {
|
||||
@@ -333,10 +333,10 @@ public:
|
||||
Standard_Integer c=i1>>5;
|
||||
Standard_Integer o=i1 & 31;
|
||||
if(TabBit[i0][c] & Mask32[o]) {
|
||||
//-- cout<<" TRUE "<<endl;
|
||||
//-- std::cout<<" TRUE "<<std::endl;
|
||||
return(Standard_True);
|
||||
}
|
||||
//-- cout<<" FALSE "<<endl;
|
||||
//-- std::cout<<" FALSE "<<std::endl;
|
||||
return(Standard_False);
|
||||
}
|
||||
//-- ============================================================
|
||||
@@ -418,7 +418,7 @@ HLRBRep_Data::HLRBRep_Data (const Standard_Integer NV,
|
||||
}
|
||||
|
||||
void HLRBRep_Data::Destroy() {
|
||||
//-- cout<<"\n HLRBRep_Data::~HLRBRep_Data()"<<endl;
|
||||
//-- std::cout<<"\n HLRBRep_Data::~HLRBRep_Data()"<<std::endl;
|
||||
((TableauRejection *)myReject)->Destroy();
|
||||
delete ((TableauRejection *)myReject);
|
||||
}
|
||||
@@ -1190,7 +1190,7 @@ void HLRBRep_Data::NextInterference ()
|
||||
GetSingleIntersection(myLE,myFE,su,sv);
|
||||
if(su!=RealLast()) {
|
||||
myIntersector.SimulateOnePoint(myLEData,su,myFEData,sv);
|
||||
//-- cout<<"p";
|
||||
//-- std::cout<<"p";
|
||||
}
|
||||
else {
|
||||
myIntersector.Perform
|
||||
@@ -1224,13 +1224,13 @@ void HLRBRep_Data::NextInterference ()
|
||||
else {
|
||||
myNbPoints = myNbSegments = 0;
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::NextInterference : ";
|
||||
std::cout << "HLRBRep_Data::NextInterference : ";
|
||||
if (myLE == myFE)
|
||||
cout << "Edge " << myLE
|
||||
<< " : Intersection not done" << endl;
|
||||
std::cout << "Edge " << myLE
|
||||
<< " : Intersection not done" << std::endl;
|
||||
else
|
||||
cout << "Edges " << myLE << " , " << myFE
|
||||
<< " : Intersection not done" << endl;
|
||||
std::cout << "Edges " << myLE << " , " << myFE
|
||||
<< " : Intersection not done" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1246,7 +1246,7 @@ void HLRBRep_Data::NextInterference ()
|
||||
}
|
||||
}
|
||||
else {
|
||||
//-- cout<<"+";
|
||||
//-- std::cout<<"+";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1391,7 +1391,7 @@ void HLRBRep_Data::EdgeState (const Standard_Real p1,
|
||||
stbef = TopAbs_OUT;
|
||||
staft = TopAbs_OUT;
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::EdgeState : undefined" << endl;
|
||||
std::cout << "HLRBRep_Data::EdgeState : undefined" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1399,7 +1399,7 @@ void HLRBRep_Data::EdgeState (const Standard_Real p1,
|
||||
stbef = TopAbs_OUT;
|
||||
staft = TopAbs_OUT;
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::EdgeState : undefined" << endl;
|
||||
std::cout << "HLRBRep_Data::EdgeState : undefined" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1464,8 +1464,8 @@ HLRBRep_Data::HidingStartLevel (const Standard_Integer E,
|
||||
Loop = Standard_False;
|
||||
else {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::HidingStartLevel : ";
|
||||
cout << "Bad Parameter." << endl;
|
||||
std::cout << "HLRBRep_Data::HidingStartLevel : ";
|
||||
std::cout << "Bad Parameter." << std::endl;
|
||||
#endif
|
||||
}
|
||||
It.Next();
|
||||
@@ -1548,9 +1548,9 @@ Standard_Boolean HLRBRep_Data::OrientOutLine (const Standard_Integer I, HLRBRep_
|
||||
gp_Vec Nm = mySLProps.Normal();
|
||||
if (curv == 0) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
cout << " Edge " << myFE << " : ";
|
||||
cout << "CurvatureValue == 0." << endl;
|
||||
std::cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
std::cout << " Edge " << myFE << " : ";
|
||||
std::cout << "CurvatureValue == 0." << std::endl;
|
||||
#endif
|
||||
}
|
||||
if (curv > 0)
|
||||
@@ -1561,9 +1561,9 @@ Standard_Boolean HLRBRep_Data::OrientOutLine (const Standard_Integer I, HLRBRep_
|
||||
Nm.Cross(Tg);
|
||||
if (Tg.Magnitude() < gp::Resolution()) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
cout << " Edge " << myFE << " : ";
|
||||
cout << "Tg.Magnitude() == 0." << endl;
|
||||
std::cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
std::cout << " Edge " << myFE << " : ";
|
||||
std::cout << "Tg.Magnitude() == 0." << std::endl;
|
||||
#endif
|
||||
}
|
||||
if (myProj.Perspective())
|
||||
@@ -1583,9 +1583,9 @@ Standard_Boolean HLRBRep_Data::OrientOutLine (const Standard_Integer I, HLRBRep_
|
||||
}
|
||||
else {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
cout << " Edge " << myFE << " : ";
|
||||
cout << "UVPoint not found, OutLine not Oriented" << endl;
|
||||
std::cout << "HLRBRep_Data::OrientOutLine " << I;
|
||||
std::cout << " Edge " << myFE << " : ";
|
||||
std::cout << "UVPoint not found, OutLine not Oriented" << std::endl;
|
||||
#endif
|
||||
}
|
||||
ed1.Used(Standard_True);
|
||||
@@ -1644,9 +1644,9 @@ void HLRBRep_Data::OrientOthEdge (const Standard_Integer I,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << "HLRBRep_Data::OrientOthEdge " << I;
|
||||
cout << " Edge " << myFE << " : ";
|
||||
cout << "UVPoint not found, Edge not Oriented" << endl;
|
||||
std::cout << "HLRBRep_Data::OrientOthEdge " << I;
|
||||
std::cout << " Edge " << myFE << " : ";
|
||||
std::cout << "UVPoint not found, Edge not Oriented" << std::endl;
|
||||
}
|
||||
#else
|
||||
(void)I; // avoid compiler warning
|
||||
@@ -1863,7 +1863,7 @@ HLRBRep_Data::Classify (const Standard_Integer E,
|
||||
q2 = (q& 0x0000FFFF);
|
||||
printf("\nmot: %3d q1 = %+10d q2=%+10d Mask : %d",qwe+8,(q1>32768)? (32768-q1) : q1,(q2>32768)? (32768-q2) : q2,q&0x80008000);
|
||||
}
|
||||
cout<<endl;
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
@@ -235,7 +235,7 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
ILOn.Remove(It); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state staft" << endl;
|
||||
std::cout << "UNKNOWN state staft" << std::endl;
|
||||
#endif
|
||||
case TopAbs_ON :
|
||||
It.Next(); break;
|
||||
@@ -249,7 +249,7 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
ILOn.Remove(It); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state stbef" << endl;
|
||||
std::cout << "UNKNOWN state stbef" << std::endl;
|
||||
#endif
|
||||
case TopAbs_ON :
|
||||
It.Next(); break;
|
||||
@@ -279,7 +279,7 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
ILOn.Remove(It); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state after" << endl;
|
||||
std::cout << "UNKNOWN state after" << std::endl;
|
||||
#endif
|
||||
It.Next(); break;
|
||||
} break;
|
||||
@@ -299,7 +299,7 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
Int.Transition(TopAbs_REVERSED); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state after" << endl;
|
||||
std::cout << "UNKNOWN state after" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -317,13 +317,13 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
ILOn.Remove(It); break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state after" << endl;
|
||||
std::cout << "UNKNOWN state after" << std::endl;
|
||||
#endif
|
||||
It.Next(); break;
|
||||
} break;
|
||||
case TopAbs_UNKNOWN :
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "UNKNOWN state stbef" << endl;
|
||||
std::cout << "UNKNOWN state stbef" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -370,14 +370,14 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
{
|
||||
ToRemove.Append(Int.Intersection().Parameter());
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<"Two adjacent interferences with transition FORWARD"<<endl;
|
||||
std::cout<<"Two adjacent interferences with transition FORWARD"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
else if (aTrans == TopAbs_REVERSED)
|
||||
{
|
||||
ToRemove.Append(PrevParam);
|
||||
#ifdef OCCT_DEBUG
|
||||
cout<<"Two adjacent interferences with transition REVERSED"<<endl;
|
||||
std::cout<<"Two adjacent interferences with transition REVERSED"<<std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -698,9 +698,9 @@ void HLRBRep_Hider::Hide(const Standard_Integer FI,
|
||||
|
||||
catch(Standard_Failure const& anException) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "An exception was catched when hiding edge " << E;
|
||||
cout << " by the face " << FI << endl;
|
||||
cout << anException << endl;
|
||||
std::cout << "An exception was catched when hiding edge " << E;
|
||||
std::cout << " by the face " << FI << std::endl;
|
||||
std::cout << anException << std::endl;
|
||||
#endif
|
||||
(void)anException;
|
||||
}
|
||||
|
@@ -114,9 +114,9 @@ void HLRBRep_InternalAlgo::Update ()
|
||||
catch(Standard_Failure const& anException) {
|
||||
if (myDebug)
|
||||
{
|
||||
cout << "An exception was catched when preparing the Shape " << i;
|
||||
cout << " and computing its OutLines " << endl;
|
||||
cout << anException << endl;
|
||||
std::cout << "An exception was catched when preparing the Shape " << i;
|
||||
std::cout << " and computing its OutLines " << std::endl;
|
||||
std::cout << anException << std::endl;
|
||||
}
|
||||
DS[i-1] = new HLRBRep_Data(0,0,0);
|
||||
dv = 0;
|
||||
@@ -165,7 +165,7 @@ void HLRBRep_InternalAlgo::Update ()
|
||||
SB.Bounds(v1,v2,e1,e2,f1,f2);
|
||||
|
||||
for (Standard_Integer e = e1; e <= e2; e++) {
|
||||
HLRBRep_EdgeData ed = aEDataArray.ChangeValue(e);
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
HLRAlgo::DecodeMinMax(ed.MinMax(), TheMin, TheMax);
|
||||
if (FirstTime) {
|
||||
FirstTime = Standard_False;
|
||||
@@ -307,7 +307,7 @@ void HLRBRep_InternalAlgo::InitEdgeStatus ()
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData ed = aEDataArray.ChangeValue(e);
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
if (ed.Selected()) ed.Status().ShowAll();
|
||||
}
|
||||
// for (Standard_Integer f = 1; f <= nf; f++) {
|
||||
@@ -368,7 +368,7 @@ void HLRBRep_InternalAlgo::Select ()
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData ed = aEDataArray.ChangeValue(e);
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
ed.Selected(Standard_True);
|
||||
}
|
||||
|
||||
@@ -556,7 +556,7 @@ void HLRBRep_InternalAlgo::PartialHide ()
|
||||
Standard_Integer i,n = myShapes.Length();
|
||||
|
||||
if (myDebug)
|
||||
cout << " Partial hiding" << endl << endl;
|
||||
std::cout << " Partial hiding" << std::endl << std::endl;
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
Hide(i);
|
||||
@@ -576,7 +576,7 @@ void HLRBRep_InternalAlgo::Hide ()
|
||||
Standard_Integer i,j,n = myShapes.Length();
|
||||
|
||||
if (myDebug)
|
||||
cout << " Total hiding" << endl;
|
||||
std::cout << " Total hiding" << std::endl;
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
Hide(i);
|
||||
@@ -602,7 +602,7 @@ void HLRBRep_InternalAlgo::Hide (const Standard_Integer I)
|
||||
"HLRBRep_InternalAlgo::Hide : unknown Shape");
|
||||
|
||||
if (myDebug)
|
||||
cout << " hiding the shape " << I << " by itself" << endl;
|
||||
std::cout << " hiding the shape " << I << " by itself" << std::endl;
|
||||
|
||||
Select(I);
|
||||
InitEdgeStatus();
|
||||
@@ -643,8 +643,8 @@ void HLRBRep_InternalAlgo::Hide (const Standard_Integer I,
|
||||
((MinMaxShBJ->Max[6] - MinMaxShBI->Min[6]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBJ->Max[7] - MinMaxShBI->Min[7]) & 0x80008000) == 0) {
|
||||
if (myDebug) {
|
||||
cout << " hiding the shape " << I;
|
||||
cout << " by the shape : " << J << endl;
|
||||
std::cout << " hiding the shape " << I;
|
||||
std::cout << " by the shape : " << J << std::endl;
|
||||
}
|
||||
SelectEdge(I);
|
||||
SelectFace(J);
|
||||
@@ -717,17 +717,17 @@ void HLRBRep_InternalAlgo::HideSelected (const Standard_Integer I,
|
||||
|
||||
if (myDebug)
|
||||
{
|
||||
cout << endl;
|
||||
cout << "Vertices : " << setw(5) << myDS->NbVertices() << endl;
|
||||
cout << "Edges : " << setw(5) << myDS->NbEdges() << " , ";
|
||||
cout << "Selected : " << setw(5) << nbSelEdges << " , ";
|
||||
cout << "Visibles : " << setw(5) << nbVisEdges << endl;
|
||||
cout << "Faces : " << setw(5) << myDS->NbFaces() << " , ";
|
||||
cout << "Selected : " << setw(5) << nbSelFaces << " , ";
|
||||
cout << "Simple : " << setw(5) << nbFSimp << endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "Vertices : " << std::setw(5) << myDS->NbVertices() << std::endl;
|
||||
std::cout << "Edges : " << std::setw(5) << myDS->NbEdges() << " , ";
|
||||
std::cout << "Selected : " << std::setw(5) << nbSelEdges << " , ";
|
||||
std::cout << "Visibles : " << std::setw(5) << nbVisEdges << std::endl;
|
||||
std::cout << "Faces : " << std::setw(5) << myDS->NbFaces() << " , ";
|
||||
std::cout << "Selected : " << std::setw(5) << nbSelFaces << " , ";
|
||||
std::cout << "Simple : " << std::setw(5) << nbFSimp << std::endl;
|
||||
if (SideFace)
|
||||
cout << "Side : " << setw(5) << nbFSide << " , ";
|
||||
cout << "Cachantes : " << setw(5) << nbCache << endl << endl;
|
||||
std::cout << "Side : " << std::setw(5) << nbFSide << " , ";
|
||||
std::cout << "Cachantes : " << std::setw(5) << nbCache << std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,13 +748,13 @@ void HLRBRep_InternalAlgo::HideSelected (const Standard_Integer I,
|
||||
if(++QWE>QWEQWE) {
|
||||
QWE=0;
|
||||
if (myDebug)
|
||||
cout<<"*";
|
||||
std::cout<<"*";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (myDebug && HLRBRep_InternalAlgo_TRACE) {
|
||||
j++;
|
||||
cout << " OwnHiding " << j << " of face : " << f << endl;
|
||||
std::cout << " OwnHiding " << j << " of face : " << f << std::endl;
|
||||
}
|
||||
}
|
||||
Cache.OwnHiding(f);
|
||||
@@ -867,7 +867,7 @@ void HLRBRep_InternalAlgo::HideSelected (const Standard_Integer I,
|
||||
if(HLRBRep_InternalAlgo_TRACE10 && HLRBRep_InternalAlgo_TRACE==Standard_False) {
|
||||
if(++QWE>QWEQWE) {
|
||||
if (myDebug)
|
||||
cout<<".";
|
||||
std::cout<<".";
|
||||
QWE=0;
|
||||
}
|
||||
}
|
||||
@@ -892,22 +892,22 @@ void HLRBRep_InternalAlgo::HideSelected (const Standard_Integer I,
|
||||
nbFSimp++;
|
||||
}
|
||||
|
||||
cout << "\n";
|
||||
cout << "Simple Faces : ";
|
||||
cout << nbFSimp << "\n";
|
||||
cout << "Intersections calculees : ";
|
||||
cout << nbCal2Intersection << "\n";
|
||||
cout << "Intersections Ok : ";
|
||||
cout << nbOkIntersection << "\n";
|
||||
cout << "Points : ";
|
||||
cout << nbPtIntersection << "\n";
|
||||
cout << "Segments : ";
|
||||
cout << nbSegIntersection << "\n";
|
||||
cout << "Classification : ";
|
||||
cout << nbClassification << "\n";
|
||||
cout << "Intersections curve-surface : ";
|
||||
cout << nbCal3Intersection << "\n";
|
||||
cout << endl << endl;
|
||||
std::cout << "\n";
|
||||
std::cout << "Simple Faces : ";
|
||||
std::cout << nbFSimp << "\n";
|
||||
std::cout << "Intersections calculees : ";
|
||||
std::cout << nbCal2Intersection << "\n";
|
||||
std::cout << "Intersections Ok : ";
|
||||
std::cout << nbOkIntersection << "\n";
|
||||
std::cout << "Points : ";
|
||||
std::cout << nbPtIntersection << "\n";
|
||||
std::cout << "Segments : ";
|
||||
std::cout << nbSegIntersection << "\n";
|
||||
std::cout << "Classification : ";
|
||||
std::cout << nbClassification << "\n";
|
||||
std::cout << "Intersections curve-surface : ";
|
||||
std::cout << nbCal3Intersection << "\n";
|
||||
std::cout << std::endl << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -159,7 +159,7 @@ public:
|
||||
|
||||
static Standard_Integer NbSamples (const gp_Lin& C, const Standard_Real U0, const Standard_Real U1);
|
||||
|
||||
Standard_EXPORT static void SamplePars (const gp_Lin& C, const Standard_Real U0, const Standard_Real U1, const Standard_Real Defl, const Standard_Integer NbMin, Handle(TColStd_HArray1OfReal)& Pars);
|
||||
static void SamplePars (const gp_Lin& C, const Standard_Real U0, const Standard_Real U1, const Standard_Real Defl, const Standard_Integer NbMin, Handle(TColStd_HArray1OfReal)& Pars);
|
||||
|
||||
|
||||
|
||||
|
@@ -438,13 +438,20 @@ void HLRBRep_PolyAlgo::StoreShell (const TopoDS_Shape& Shape,
|
||||
PD (f) = new HLRAlgo_PolyData();
|
||||
psd->PolyData().ChangeValue(iFace) = PD(f);
|
||||
PID(f) = new HLRAlgo_PolyInternalData(nbN,nbT);
|
||||
Handle(HLRAlgo_PolyInternalData)& pid =
|
||||
*(Handle(HLRAlgo_PolyInternalData)*)&(PID(f));
|
||||
Handle(Geom_Surface) S = BRep_Tool::Surface(F);
|
||||
if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
|
||||
S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
|
||||
Handle(HLRAlgo_PolyInternalData)& pid = *(Handle(HLRAlgo_PolyInternalData)*)&(PID(f));
|
||||
if (Handle(Geom_Surface) S = BRep_Tool::Surface(F))
|
||||
{
|
||||
if (Handle(Geom_RectangularTrimmedSurface) aRectTrimSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast(S))
|
||||
{
|
||||
S = aRectTrimSurf->BasisSurface();
|
||||
}
|
||||
GeomAdaptor_Surface AS(S);
|
||||
pid->Planar(AS.GetType() == GeomAbs_Plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
pid->Planar (false);
|
||||
}
|
||||
HLRAlgo_Array1OfTData* TData = &pid->TData();
|
||||
HLRAlgo_Array1OfPISeg* PISeg = &pid->PISeg();
|
||||
HLRAlgo_Array1OfPINod* PINod = &pid->PINod();
|
||||
@@ -501,8 +508,8 @@ void HLRBRep_PolyAlgo::StoreShell (const TopoDS_Shape& Shape,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << " HLRBRep_PolyAlgo::StoreShell : Face ";
|
||||
cout << f << " non triangulated" << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::StoreShell : Face ";
|
||||
std::cout << f << " non triangulated" << std::endl;
|
||||
}
|
||||
#endif
|
||||
NT = &(((HLRAlgo_Array1OfTData*)TData)->ChangeValue(1));
|
||||
@@ -527,8 +534,8 @@ void HLRBRep_PolyAlgo::StoreShell (const TopoDS_Shape& Shape,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::StoreShell : Face ";
|
||||
cout << f << " deja stockee" << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::StoreShell : Face ";
|
||||
std::cout << f << " deja stockee" << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -656,8 +663,8 @@ Normal (const Standard_Integer iNode,
|
||||
Nod1RValues.Normal = gp_XYZ(1., 0., 0.);
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::Normal : AverageNormal error";
|
||||
cout << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::Normal : AverageNormal error";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -733,8 +740,8 @@ HLRBRep_PolyAlgo::AverageNormal(const Standard_Integer iNode,
|
||||
OK = Standard_False;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRAlgo_PolyInternalData:: inverted normals on ";
|
||||
cout << "node " << iNode << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData:: inverted normals on ";
|
||||
std::cout << "node " << iNode << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -875,8 +882,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
else if (aNode12Indices->Edg2 == e) U2 = Nod12RValues->PCu2;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
aNode12Indices->Flag |= NMsk_Edge;
|
||||
@@ -906,10 +913,10 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
if (Nod11RValues->Normal.X()*Nod12RValues->Normal.X() +
|
||||
Nod11RValues->Normal.Y()*Nod12RValues->Normal.Y() +
|
||||
Nod11RValues->Normal.Z()*Nod12RValues->Normal.Z() < 0) {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Too big angle between " << i1p1 << setw(6);
|
||||
cout << " and " << i1p2 << setw(6);
|
||||
cout << " in face " << i1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Too big angle between " << i1p1 << std::setw(6);
|
||||
std::cout << " and " << i1p2 << std::setw(6);
|
||||
std::cout << " in face " << i1 << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -927,8 +934,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
else if (aNode12Indices->Edg2 == e) U2 = Nod12RValues->PCu2;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
aNode12Indices->Flag |= NMsk_Edge;
|
||||
@@ -945,8 +952,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
cout << e << " connex 1 sans PolygonOnTriangulation" << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
std::cout << e << " connex 1 sans PolygonOnTriangulation" << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1041,8 +1048,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
else if (aNode12Indices->Edg2 == e) U2 = Nod12RValues->PCu2;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
aNode12Indices->Flag |= NMsk_Edge;
|
||||
@@ -1085,18 +1092,18 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
if (Nod11RValues->Normal.X()*Nod12RValues->Normal.X() +
|
||||
Nod11RValues->Normal.Y()*Nod12RValues->Normal.Y() +
|
||||
Nod11RValues->Normal.Z()*Nod12RValues->Normal.Z() < 0) {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "To big angle between " << i1p1 << setw(6);
|
||||
cout << " and " << i1p2 << setw(6);
|
||||
cout << " in face " << i1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "To big angle between " << i1p1 << std::setw(6);
|
||||
std::cout << " and " << i1p2 << std::setw(6);
|
||||
std::cout << " in face " << i1 << std::endl;
|
||||
}
|
||||
if (Nod21RValues->Normal.X()*Nod22RValues->Normal.X() +
|
||||
Nod21RValues->Normal.Y()*Nod22RValues->Normal.Y() +
|
||||
Nod21RValues->Normal.Z()*Nod22RValues->Normal.Z() < 0) {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "To big angle between " << i2p1 << setw(6);
|
||||
cout << " and " << i2p2 << setw(6);
|
||||
cout<< " in face " << i2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "To big angle between " << i2p1 << std::setw(6);
|
||||
std::cout << " and " << i2p2 << std::setw(6);
|
||||
std::cout<< " in face " << i2 << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1114,8 +1121,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
else if (aNode12Indices->Edg2 == e) U2 = Nod12RValues->PCu2;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::InitBiPointsWithConnexity : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
aNode12Indices->Flag |= NMsk_Edge;
|
||||
@@ -1136,8 +1143,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
cout << e << " connect 2 without PolygonOnTriangulation" << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
std::cout << e << " connect 2 without PolygonOnTriangulation" << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1198,8 +1205,8 @@ InitBiPointsWithConnexity (const Standard_Integer e,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
cout << e << " Isolated, without Polygone 3D" << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::InitBiPointsWithConnexity : Edge ";
|
||||
std::cout << e << " Isolated, without Polygone 3D" << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1489,8 +1496,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod11Indices.Edg2 == e) Nod11RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod11RValues.Scal = 0;
|
||||
@@ -1521,8 +1528,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod12Indices.Edg2 == e) Nod12RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod12RValues.Scal = 0;
|
||||
@@ -1644,8 +1651,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod11Indices.Edg2 == e) Nod11RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod11RValues.Scal = 0;
|
||||
@@ -1656,8 +1663,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod21Indices.Edg2 == e) Nod21RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i2p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i2p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod21RValues.Scal = 0;
|
||||
@@ -1693,8 +1700,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod12Indices.Edg2 == e) Nod12RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod12RValues.Scal = 0;
|
||||
@@ -1705,8 +1712,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod22Indices.Edg2 == e) Nod22RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i2p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i2p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod22RValues.Scal = 0;
|
||||
@@ -1853,8 +1860,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod11Indices.Edg2 == e) Nod11RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod11RValues.Scal = 0;
|
||||
@@ -1865,8 +1872,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod21Indices.Edg2 == e) Nod21RValues.PCu2 = U3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i2p1 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i2p1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod21RValues.Scal = 0;
|
||||
@@ -1902,8 +1909,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod12Indices.Edg2 == e) Nod12RValues.PCu2 = U4;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i1p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i1p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod12RValues.Scal = 0;
|
||||
@@ -1914,8 +1921,8 @@ MoveOrInsertPoint (HLRAlgo_ListOfBPoint& List,
|
||||
else if (Nod22Indices.Edg2 == e) Nod22RValues.PCu2 = U4;
|
||||
#ifdef OCCT_DEBUG
|
||||
else {
|
||||
cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
cout << "Parameter error on Node " << i2p2 << endl;
|
||||
std::cout << " HLRBRep_PolyAlgo::MoveOrInsertPoint : ";
|
||||
std::cout << "Parameter error on Node " << i2p2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
Nod22RValues.Scal = 0;
|
||||
@@ -2078,9 +2085,9 @@ HLRBRep_PolyAlgo::InsertOnOutLine (TColStd_Array1OfTransient& PID)
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << " InsertOnOutLine : NbTData " << (*pid)->NbTData() << endl;
|
||||
cout << " InsertOnOutLine : NbPISeg " << (*pid)->NbPISeg() << endl;
|
||||
cout << " InsertOnOutLine : NbPINod " << (*pid)->NbPINod() << endl;
|
||||
std::cout << " InsertOnOutLine : NbTData " << (*pid)->NbTData() << std::endl;
|
||||
std::cout << " InsertOnOutLine : NbPISeg " << (*pid)->NbPISeg() << std::endl;
|
||||
std::cout << " InsertOnOutLine : NbPINod " << (*pid)->NbPINod() << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2162,9 +2169,9 @@ HLRBRep_PolyAlgo::InsertOnOutLine (TColStd_Array1OfTransient& PID)
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << " InsertOnOutLine : NbTData " << (*pid)->NbTData() << endl;
|
||||
cout << " InsertOnOutLine : NbPISeg " << (*pid)->NbPISeg() << endl;
|
||||
cout << " InsertOnOutLine : NbPINod " << (*pid)->NbPINod() << endl;
|
||||
std::cout << " InsertOnOutLine : NbTData " << (*pid)->NbTData() << std::endl;
|
||||
std::cout << " InsertOnOutLine : NbPISeg " << (*pid)->NbPISeg() << std::endl;
|
||||
std::cout << " InsertOnOutLine : NbPINod " << (*pid)->NbPINod() << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2241,7 +2248,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
(tdata->Flags & HLRAlgo_PolyMask_FMskFrBack)) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << " face : " << f << " , triangle " << i << endl;
|
||||
std::cout << " face : " << f << " , triangle " << i << std::endl;
|
||||
#endif
|
||||
Modif = Standard_True;
|
||||
const Handle(HLRAlgo_PolyInternalNode)* pi1p1 =
|
||||
@@ -2310,8 +2317,8 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
FrBackInList = Standard_True;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << tdata->Node1 << " modifies : DX,DY ";
|
||||
cout << X1 << " , " << Y1 << endl;
|
||||
std::cout << tdata->Node1 << " modifies : DX,DY ";
|
||||
std::cout << X1 << " , " << Y1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2323,8 +2330,8 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
FrBackInList = Standard_True;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << tdata->Node2 << " modifies : DX,DY ";
|
||||
cout << X2 << " , " << Y2 << endl;
|
||||
std::cout << tdata->Node2 << " modifies : DX,DY ";
|
||||
std::cout << X2 << " , " << Y2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2336,14 +2343,14 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
FrBackInList = Standard_True;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << tdata->Node3 << " modifies : DX,DY ";
|
||||
cout << X3 << " , " << Y3 << endl;
|
||||
std::cout << tdata->Node3 << " modifies : DX,DY ";
|
||||
std::cout << X3 << " , " << Y3 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoTrace)
|
||||
cout << "modification error" << endl;
|
||||
std::cout << "modification error" << std::endl;
|
||||
#endif
|
||||
}
|
||||
tdata++;
|
||||
@@ -2383,7 +2390,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
if (Nod11Indices->Flag & NMsk_Move) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << theIndices.Face1Pt1 << " modifies 11" << endl;
|
||||
std::cout << theIndices.Face1Pt1 << " modifies 11" << std::endl;
|
||||
#endif
|
||||
Nod11RValues = &PINod1->ChangeValue(theIndices.Face1Pt1)->Data();
|
||||
HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
|
||||
@@ -2402,7 +2409,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
if (Nod11Indices->Flag & NMsk_Move) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << theIndices.Face1Pt2 << " modifies 12" << endl;
|
||||
std::cout << theIndices.Face1Pt2 << " modifies 12" << std::endl;
|
||||
#endif
|
||||
Nod11RValues = &PINod1->ChangeValue(theIndices.Face1Pt2)->Data();
|
||||
HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
|
||||
@@ -2426,7 +2433,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
if (Nod11Indices->Flag & NMsk_Move) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << theIndices.Face2Pt1 << " modifies 21" << endl;
|
||||
std::cout << theIndices.Face2Pt1 << " modifies 21" << std::endl;
|
||||
#endif
|
||||
Nod11RValues = &PINod2->ChangeValue(theIndices.Face2Pt1)->Data();
|
||||
HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
|
||||
@@ -2445,7 +2452,7 @@ HLRBRep_PolyAlgo::CheckFrBackTriangles (HLRAlgo_ListOfBPoint& List,
|
||||
if (Nod11Indices->Flag & NMsk_Move) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace)
|
||||
cout << theIndices.Face2Pt2 << " modifies 22" << endl;
|
||||
std::cout << theIndices.Face2Pt2 << " modifies 22" << std::endl;
|
||||
#endif
|
||||
Nod11RValues = &PINod2->ChangeValue(theIndices.Face2Pt2)->Data();
|
||||
HLRAlgo_BiPoint::PointsT& aPoints = BP.Points();
|
||||
@@ -2563,8 +2570,8 @@ void HLRBRep_PolyAlgo::ChangeNode (const Standard_Integer ip1,
|
||||
Nod1RValues.Normal = gp_XYZ(1., 0., 0.);
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::ChangeNode between " << ip1;
|
||||
cout << " and " << ip2 << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::ChangeNode between " << ip1;
|
||||
std::cout << " and " << ip2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2583,8 +2590,8 @@ void HLRBRep_PolyAlgo::ChangeNode (const Standard_Integer ip1,
|
||||
Nod2RValues.Normal = gp_XYZ(1., 0., 0.);
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::ChangeNode between " << ip2;
|
||||
cout << " and " << ip1 << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::ChangeNode between " << ip2;
|
||||
std::cout << " and " << ip1 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2684,8 +2691,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskOnOutL;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : OnOutL";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : OnOutL";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -2717,8 +2724,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
if (aD12Norm <= 1.e-10) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskFlat;
|
||||
@@ -2731,8 +2738,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
if (aD23Norm < 1.e-10) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskFlat;
|
||||
@@ -2745,8 +2752,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
if (aD31Norm < 1.e-10) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskFlat;
|
||||
@@ -2761,8 +2768,8 @@ HLRBRep_PolyAlgo::OrientTriangle(const Standard_Integer,
|
||||
if (aDNorm < 1.e-5) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
cout << " triangle " << iTri << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::OrientTriangle : Flat";
|
||||
std::cout << " triangle " << iTri << std::endl;
|
||||
}
|
||||
#endif
|
||||
theTriangle.Flags |= HLRAlgo_PolyMask_FMskFlat;
|
||||
@@ -2838,8 +2845,8 @@ HLRBRep_PolyAlgo::Triangles(const Standard_Integer ip1,
|
||||
iTri2 = 0;
|
||||
#ifdef OCCT_DEBUG
|
||||
if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::Triangles : error";
|
||||
cout << " between " << ip1 << " and " << ip2 << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::Triangles : error";
|
||||
std::cout << " between " << ip1 << " and " << ip2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
return Standard_False;
|
||||
@@ -2975,8 +2982,8 @@ HLRBRep_PolyAlgo::UpdateOutLines (HLRAlgo_ListOfBPoint& List,
|
||||
aTriangle.Flags |= HLRAlgo_PolyMask_EMskOutLin3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
|
||||
cout << " : segment not found" << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
|
||||
std::cout << " : segment not found" << std::endl;
|
||||
}
|
||||
#endif
|
||||
tn1 = aTriangle2.Node1;
|
||||
@@ -2995,8 +3002,8 @@ HLRBRep_PolyAlgo::UpdateOutLines (HLRAlgo_ListOfBPoint& List,
|
||||
aTriangle2.Flags |= HLRAlgo_PolyMask_EMskOutLin3;
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
|
||||
cout << " : segment not found" << endl;
|
||||
std::cout << "HLRAlgo_PolyInternalData::UpdateOutLines";
|
||||
std::cout << " : segment not found" << std::endl;
|
||||
}
|
||||
#endif
|
||||
HLRAlgo_PolyInternalNode::NodeData& Nod1RValues =
|
||||
@@ -3081,9 +3088,9 @@ UpdateEdgesBiPoints (HLRAlgo_ListOfBPoint& List,
|
||||
}
|
||||
#ifdef OCCT_DEBUG
|
||||
else if (DoError) {
|
||||
cout << "HLRBRep_PolyAlgo::UpdateEdgesBiPoints : error ";
|
||||
cout << " between " << aIndices.FaceConex1 << setw(6);
|
||||
cout << " and " << aIndices.FaceConex2 << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::UpdateEdgesBiPoints : error ";
|
||||
std::cout << " between " << aIndices.FaceConex1 << std::setw(6);
|
||||
std::cout << " and " << aIndices.FaceConex2 << std::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -3133,9 +3140,9 @@ HLRBRep_PolyAlgo::UpdatePolyData (TColStd_Array1OfTransient& PD,
|
||||
if (!(OT->Flags & HLRAlgo_PolyMask_FMskSide)) {
|
||||
#ifdef OCCT_DEBUG
|
||||
if ((OT->Flags & HLRAlgo_PolyMask_FMskFrBack) && DoTrace) {
|
||||
cout << "HLRBRep_PolyAlgo::ReverseBackTriangle :";
|
||||
cout << " face " << f << setw(6);
|
||||
cout << " triangle " << i << endl;
|
||||
std::cout << "HLRBRep_PolyAlgo::ReverseBackTriangle :";
|
||||
std::cout << " face " << f << std::setw(6);
|
||||
std::cout << " triangle " << i << std::endl;
|
||||
}
|
||||
#endif
|
||||
if (OT->Flags & HLRAlgo_PolyMask_FMskOrBack) {
|
||||
|
@@ -49,7 +49,7 @@ public:
|
||||
//! <V> on the Surface <A>.
|
||||
static void D2 (const Standard_Address A, const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& DUV);
|
||||
|
||||
Standard_EXPORT static gp_Vec DN (const Standard_Address A, const Standard_Real U, const Standard_Real V, const Standard_Integer Nu, const Standard_Integer Nv);
|
||||
static gp_Vec DN (const Standard_Address A, const Standard_Real U, const Standard_Real V, const Standard_Integer Nu, const Standard_Integer Nv);
|
||||
|
||||
//! returns the order of continuity of the Surface
|
||||
//! <A>. returns 1 : first derivative only is
|
||||
|
@@ -33,7 +33,6 @@
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
|
@@ -228,7 +228,7 @@ void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
|
||||
|
||||
if(ipL-ipF < 1) {
|
||||
InsuffisantNumberOfPoints=Standard_True;
|
||||
//cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<<endl;
|
||||
//std::cout<<"\n !! Pb ds HLRTopoBRep_DSFiller.cxx (Contour App Nbp <3)"<<std::endl;
|
||||
}
|
||||
/*
|
||||
else if(ipL-ipF < 6) {
|
||||
@@ -390,7 +390,7 @@ void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
|
||||
TOL3d=TOL*Maxx; if(TOL3d<1e-12) TOL3d=1e-12; else if(TOL3d>0.1) TOL3d=0.1;
|
||||
TOL2d=TOL*Maxu; if(TOL2d<1e-12) TOL2d=1e-12; else if(TOL2d>0.1) TOL2d=0.1;
|
||||
|
||||
//-- cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<" Tol3d="<<TOL3d<<" Tol2d="<<TOL2d<<endl;
|
||||
//-- std::cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<" Tol3d="<<TOL3d<<" Tol2d="<<TOL2d<<std::endl;
|
||||
|
||||
Approx.SetParameters(TOL3d, TOL2d, dmin, dmax, niter, 30, tg);
|
||||
Approx.Perform(AppLine,Standard_True,Standard_True,Standard_False,1,nbp);
|
||||
|
@@ -197,23 +197,23 @@ void HLRTopoBRep_FaceIsoLiner::Perform (const Standard_Integer FI,
|
||||
Hatcher.ComputeDomains (IndH);
|
||||
if (!Hatcher.IsDone (IndH)) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
|
||||
cout << "U iso of parameter: " << UPrm;
|
||||
std::cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << std::endl;
|
||||
std::cout << "U iso of parameter: " << UPrm;
|
||||
switch (Hatcher.Status (IndH)) {
|
||||
case HatchGen_NoProblem :
|
||||
cout << " No Problem" << endl;
|
||||
std::cout << " No Problem" << std::endl;
|
||||
break;
|
||||
case HatchGen_TrimFailure :
|
||||
cout << " Trim Failure" << endl;
|
||||
std::cout << " Trim Failure" << std::endl;
|
||||
break;
|
||||
case HatchGen_TransitionFailure :
|
||||
cout << " Transition Failure" << endl;
|
||||
std::cout << " Transition Failure" << std::endl;
|
||||
break;
|
||||
case HatchGen_IncoherentParity :
|
||||
cout << " Incoherent Parity" << endl;
|
||||
std::cout << " Incoherent Parity" << std::endl;
|
||||
break;
|
||||
case HatchGen_IncompatibleStates :
|
||||
cout << " Incompatible States" << endl;
|
||||
std::cout << " Incompatible States" << std::endl;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -291,23 +291,23 @@ void HLRTopoBRep_FaceIsoLiner::Perform (const Standard_Integer FI,
|
||||
Hatcher.ComputeDomains (IndH);
|
||||
if (!Hatcher.IsDone (IndH)) {
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
|
||||
cout << "V iso of parameter: " << VPrm;
|
||||
std::cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << std::endl;
|
||||
std::cout << "V iso of parameter: " << VPrm;
|
||||
switch (Hatcher.Status (IndH)) {
|
||||
case HatchGen_NoProblem :
|
||||
cout << " No Problem" << endl;
|
||||
std::cout << " No Problem" << std::endl;
|
||||
break;
|
||||
case HatchGen_TrimFailure :
|
||||
cout << " Trim Failure" << endl;
|
||||
std::cout << " Trim Failure" << std::endl;
|
||||
break;
|
||||
case HatchGen_TransitionFailure :
|
||||
cout << " Transition Failure" << endl;
|
||||
std::cout << " Transition Failure" << std::endl;
|
||||
break;
|
||||
case HatchGen_IncoherentParity :
|
||||
cout << " Incoherent Parity" << endl;
|
||||
std::cout << " Incoherent Parity" << std::endl;
|
||||
break;
|
||||
case HatchGen_IncompatibleStates :
|
||||
cout << " Incompatible States" << endl;
|
||||
std::cout << " Incompatible States" << std::endl;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@@ -296,7 +296,7 @@ IGESData_IGESReaderTool::IGESData_IGESReaderTool
|
||||
Msg34.Arg(thecnum);
|
||||
Msg34.Arg(thectyp.Type());
|
||||
ach->SendWarning(Msg34);
|
||||
ent->InitDirFieldEntity(13,fieldent);
|
||||
ent->InitDirFieldEntity(13, Color);
|
||||
}
|
||||
else ent->InitColor(Color);
|
||||
}
|
||||
|
@@ -930,21 +930,19 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
// 3. ts1 == ts2 == 0 <Param-Param>
|
||||
|
||||
// Geom - Geom
|
||||
const Standard_Boolean RestrictLine = Standard_True;
|
||||
if(ts1 == ts2 && ts1 == 1)
|
||||
{
|
||||
IntSurf_ListOfPntOn2S ListOfPnts;
|
||||
ListOfPnts.Clear();
|
||||
if(isGeomInt)
|
||||
{
|
||||
GeomGeomPerfom( theS1, theD1, theS2, theD2, TolArc,
|
||||
TolTang, ListOfPnts, RestrictLine,
|
||||
typs1, typs2, theIsReqToKeepRLine);
|
||||
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang,
|
||||
ListOfPnts, typs1, typs2, theIsReqToKeepRLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2,
|
||||
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
|
||||
TolArc, TolTang, ListOfPnts, typs1, typs2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -961,7 +959,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
ListOfPnts.Clear();
|
||||
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
|
||||
TolTang, ListOfPnts, RestrictLine, typs1, typs2);
|
||||
TolTang, ListOfPnts, typs1, typs2);
|
||||
}
|
||||
|
||||
if(!theIsReqToPostWLProc)
|
||||
@@ -978,7 +976,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
continue;
|
||||
|
||||
Handle(IntPatch_WLine) aRW =
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
|
||||
|
||||
if(aRW.IsNull())
|
||||
continue;
|
||||
@@ -999,7 +997,6 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
const Standard_Real TolArc,
|
||||
const Standard_Real TolTang,
|
||||
IntSurf_ListOfPntOn2S& ListOfPnts,
|
||||
const Standard_Boolean RestrictLine,
|
||||
const Standard_Boolean isGeomInt,
|
||||
const Standard_Boolean theIsReqToKeepRLine,
|
||||
const Standard_Boolean theIsReqToPostWLProc)
|
||||
@@ -1183,7 +1180,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
if(!isGeomInt)
|
||||
{
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2,
|
||||
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
|
||||
TolArc, TolTang, ListOfPnts, typs1, typs2);
|
||||
}
|
||||
else if(ts1 != ts2)
|
||||
{
|
||||
@@ -1192,12 +1189,12 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
else if (ts1 == 0)
|
||||
{
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2,
|
||||
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
|
||||
TolArc, TolTang, ListOfPnts, typs1, typs2);
|
||||
}
|
||||
else if(ts1 == 1)
|
||||
{
|
||||
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc,
|
||||
TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
|
||||
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, TolTang,
|
||||
ListOfPnts, typs1, typs2, theIsReqToKeepRLine);
|
||||
}
|
||||
|
||||
if(!theIsReqToPostWLProc)
|
||||
@@ -1214,7 +1211,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
|
||||
continue;
|
||||
|
||||
Handle(IntPatch_WLine) aRW =
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
|
||||
|
||||
if(aRW.IsNull())
|
||||
continue;
|
||||
@@ -1235,7 +1232,6 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
|
||||
const Standard_Real TolArc,
|
||||
const Standard_Real TolTang,
|
||||
IntSurf_ListOfPntOn2S& ListOfPnts,
|
||||
const Standard_Boolean RestrictLine,
|
||||
const GeomAbs_SurfaceType typs1,
|
||||
const GeomAbs_SurfaceType typs2)
|
||||
{
|
||||
@@ -1245,10 +1241,10 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
|
||||
Standard_Boolean ClearFlag = Standard_True;
|
||||
if(!ListOfPnts.IsEmpty())
|
||||
{
|
||||
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
|
||||
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts);
|
||||
ClearFlag = Standard_False;
|
||||
}
|
||||
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag); //double call!!!!!!!
|
||||
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag);
|
||||
}
|
||||
else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
|
||||
{
|
||||
@@ -1345,7 +1341,6 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
|
||||
const Standard_Real TolArc,
|
||||
const Standard_Real TolTang,
|
||||
IntSurf_ListOfPntOn2S& ListOfPnts,
|
||||
const Standard_Boolean RestrictLine,
|
||||
const GeomAbs_SurfaceType theTyps1,
|
||||
const GeomAbs_SurfaceType theTyps2,
|
||||
const Standard_Boolean theIsReqToKeepRLine)
|
||||
@@ -1357,7 +1352,7 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
|
||||
{
|
||||
done = Standard_False;
|
||||
ParamParamPerfom(theS1, theD1, theS2, theD2,
|
||||
TolArc, TolTang, ListOfPnts, RestrictLine, theTyps1, theTyps2);
|
||||
TolArc, TolTang, ListOfPnts, theTyps1, theTyps2);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1604,7 +1599,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
|
||||
continue;
|
||||
|
||||
Handle(IntPatch_WLine) aRW =
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2, Standard_True);
|
||||
IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2);
|
||||
|
||||
if(aRW.IsNull())
|
||||
continue;
|
||||
|
@@ -70,16 +70,16 @@ public:
|
||||
//!
|
||||
//! UVMaxStep is a parameter used in the walking
|
||||
//! algorithms to compute the distance between to
|
||||
//! points in their respective parametrtic spaces.
|
||||
//! points in their respective parametric spaces.
|
||||
Standard_EXPORT void SetTolerances (const Standard_Real TolArc, const Standard_Real TolTang, const Standard_Real UVMaxStep, const Standard_Real Fleche);
|
||||
|
||||
//! Flag theIsReqToKeepRLine has been enterred only for
|
||||
//! Flag theIsReqToKeepRLine has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! When intersection result returns IntPatch_RLine and another
|
||||
//! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
|
||||
//! will always keep both lines even if they are coincided.
|
||||
//! Flag theIsReqToPostWLProc has been enterred only for
|
||||
//! Flag theIsReqToPostWLProc has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line
|
||||
@@ -88,18 +88,18 @@ public:
|
||||
|
||||
//! If isGeomInt == Standard_False, then method
|
||||
//! Param-Param intersection will be used.
|
||||
//! Flag theIsReqToKeepRLine has been enterred only for
|
||||
//! Flag theIsReqToKeepRLine has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! When intersection result returns IntPatch_RLine and another
|
||||
//! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
|
||||
//! will always keep both lines even if they are coincided.
|
||||
//! Flag theIsReqToPostWLProc has been enterred only for
|
||||
//! Flag theIsReqToPostWLProc has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! If theIsReqToPostWLProc == FALSE, then we will work with Walking-line
|
||||
//! obtained after intersection algorithm directly (wothout any post-processing).
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine = Standard_True, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True);
|
||||
//! obtained after intersection algorithm directly (without any post-processing).
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean isGeomInt = Standard_True, const Standard_Boolean theIsReqToKeepRLine = Standard_False, const Standard_Boolean theIsReqToPostWLProc = Standard_True);
|
||||
|
||||
//! Perform with start point
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2, const Standard_Real TolArc, const Standard_Real TolTang);
|
||||
@@ -107,14 +107,14 @@ public:
|
||||
//! Uses for finding self-intersected surfaces.
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Standard_Real TolArc, const Standard_Real TolTang);
|
||||
|
||||
//! Returns True if the calculus was succesfull.
|
||||
//! Returns True if the calculus was successful.
|
||||
Standard_Boolean IsDone() const;
|
||||
|
||||
//! Returns true if the is no intersection.
|
||||
Standard_Boolean IsEmpty() const;
|
||||
|
||||
//! Returns True if the two patches are considered as
|
||||
//! entierly tangent, i-e every restriction arc of one
|
||||
//! entirely tangent, i-e every restriction arc of one
|
||||
//! patch is inside the geometric base of the other patch.
|
||||
Standard_Boolean TangentFaces() const;
|
||||
|
||||
@@ -157,15 +157,15 @@ protected:
|
||||
private:
|
||||
|
||||
|
||||
Standard_EXPORT void ParamParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
|
||||
Standard_EXPORT void ParamParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
|
||||
|
||||
//! Flag theIsReqToKeepRLine has been enterred only for
|
||||
//! Flag theIsReqToKeepRLine has been entered only for
|
||||
//! compatibility with TopOpeBRep package. It shall be deleted
|
||||
//! after deleting TopOpeBRep.
|
||||
//! When intersection result returns IntPatch_RLine and another
|
||||
//! IntPatch_Line (not restriction) we (in case of theIsReqToKeepRLine==TRUE)
|
||||
//! will always keep both lines even if they are coincided.
|
||||
Standard_EXPORT void GeomGeomPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const Standard_Boolean RestrictLine, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2, const Standard_Boolean theIsReqToKeepRLine = Standard_False);
|
||||
Standard_EXPORT void GeomGeomPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, IntSurf_ListOfPntOn2S& LOfPnts, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2, const Standard_Boolean theIsReqToKeepRLine);
|
||||
|
||||
Standard_EXPORT void GeomParamPerfom (const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Boolean isNotAnalitical, const GeomAbs_SurfaceType typs1, const GeomAbs_SurfaceType typs2);
|
||||
|
||||
|
@@ -1551,8 +1551,7 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
|
||||
const Standard_Real Epsilon,
|
||||
const Standard_Real Deflection,
|
||||
const Standard_Real Increment,
|
||||
IntSurf_ListOfPntOn2S& LOfPnts,
|
||||
const Standard_Boolean RestrictLine)
|
||||
IntSurf_ListOfPntOn2S& LOfPnts)
|
||||
{
|
||||
if (LOfPnts.IsEmpty()){
|
||||
done = Standard_True;
|
||||
@@ -1788,15 +1787,13 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
|
||||
|
||||
Standard_Real TolTang = TolTangency;
|
||||
Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
|
||||
if (RestrictLine){
|
||||
//the method PutVertexOnLine can reduce the number of points in <wline>
|
||||
IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
|
||||
IntPatch_RstInt::PutVertexOnLine(wline, Surf1, D1, Surf2, Standard_True, TolTang);
|
||||
if (wline->NbPnts() < 2)
|
||||
continue;
|
||||
IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
|
||||
IntPatch_RstInt::PutVertexOnLine(wline, Surf2, D2, Surf1, Standard_False, TolTang);
|
||||
if (wline->NbPnts() < 2)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(wline->NbVertex() == 0) {
|
||||
IntPatch_Point vtx;
|
||||
|
@@ -68,7 +68,7 @@ public:
|
||||
//! Performs the intersection between <Caro1> and
|
||||
//! <Caro2>. The method computes the polyhedron on
|
||||
//! each surface.
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_TopolTool)& Domain1, const Handle(Adaptor3d_HSurface)& Caro2, const Handle(Adaptor3d_TopolTool)& Domain2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment, IntSurf_ListOfPntOn2S& ListOfPnts, const Standard_Boolean RestrictLine);
|
||||
Standard_EXPORT void Perform (const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_TopolTool)& Domain1, const Handle(Adaptor3d_HSurface)& Caro2, const Handle(Adaptor3d_TopolTool)& Domain2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment, IntSurf_ListOfPntOn2S& ListOfPnts);
|
||||
|
||||
//! Performs the intersection between <Caro1> and
|
||||
//! <Caro2>. The method computes the polyhedron on
|
||||
|
@@ -234,40 +234,6 @@ static void GetLinePoint2d (const Handle(IntPatch_Line)& L,
|
||||
V = (1.-par)*vs1+par*vs2;
|
||||
}
|
||||
|
||||
static void GetWLinePoint (const Handle(IntPatch_WLine)& wlin,
|
||||
const Standard_Real param,
|
||||
Standard_Real& U1, Standard_Real& V1,
|
||||
Standard_Real& U2, Standard_Real& V2,
|
||||
gp_Pnt& P)
|
||||
{
|
||||
Standard_Integer Nbptlin = wlin->NbPnts();
|
||||
Standard_Real par = IntegerPart(param);
|
||||
Standard_Integer Irang = Standard_Integer(par);
|
||||
if (Irang == Nbptlin) {
|
||||
Irang--;
|
||||
par = 1.0;
|
||||
}
|
||||
else
|
||||
par = Abs(param-par);
|
||||
|
||||
const IntSurf_PntOn2S& p2s1 = wlin->Point(Irang);
|
||||
const IntSurf_PntOn2S& p2s2 = wlin->Point(Irang+1);
|
||||
const gp_Pnt& p1 = p2s1.Value();
|
||||
const gp_Pnt& p2 = p2s2.Value();
|
||||
P.ChangeCoord().SetLinearForm(1.-par, p1.XYZ(), par, p2.XYZ());
|
||||
|
||||
Standard_Real us1,vs1,us2,vs2;
|
||||
p2s1.ParametersOnS1(us1,vs1);
|
||||
p2s2.ParametersOnS1(us2,vs2);
|
||||
U1 = (1.-par)*us1+par*us2;
|
||||
V1 = (1.-par)*vs1+par*vs2;
|
||||
|
||||
p2s1.ParametersOnS2(us1,vs1);
|
||||
p2s2.ParametersOnS2(us2,vs2);
|
||||
U2 = (1.-par)*us1+par*us2;
|
||||
V2 = (1.-par)*vs1+par*vs2;
|
||||
}
|
||||
|
||||
static Standard_Boolean FindParameter(const Handle(IntPatch_Line)& L,
|
||||
const Handle(Adaptor3d_HSurface)& OtherSurf,
|
||||
const Standard_Real Tol,
|
||||
@@ -394,50 +360,6 @@ inline Standard_Boolean ArePnt2dEqual(const gp_Pnt2d& p1, const gp_Pnt2d& p2,
|
||||
return Abs(p1.X()-p2.X()) < tolU && Abs(p1.Y()-p2.Y()) < tolV;
|
||||
}
|
||||
|
||||
static gp_Pnt2d GetPointOnPolygo(const IntPatch_Polygo& Pol,
|
||||
const Standard_Real param)
|
||||
{
|
||||
Standard_Real par = IntegerPart(param);
|
||||
Standard_Integer irang = Standard_Integer(par) + 1;
|
||||
if (irang == Pol.NbPoints()) {
|
||||
irang--;
|
||||
par = 1.;
|
||||
}
|
||||
else {
|
||||
par = Abs(param-par);
|
||||
}
|
||||
gp_Pnt2d p1 = Pol.Point(irang);
|
||||
gp_Pnt2d p2 = Pol.Point(irang+1);
|
||||
gp_Pnt2d p;
|
||||
p.ChangeCoord().SetLinearForm(1.-par,p1.XY(),par,p2.XY());
|
||||
return p;
|
||||
}
|
||||
|
||||
static Standard_Boolean IsSegment2dSmall(const IntPatch_Polygo& Pol,
|
||||
const Standard_Real parmin,
|
||||
const Standard_Real parmax,
|
||||
const Standard_Real URes,
|
||||
const Standard_Real VRes)
|
||||
{
|
||||
Standard_Integer irang1 = Standard_Integer(IntegerPart(parmin)) + 2;
|
||||
Standard_Integer irang2 = Standard_Integer(IntegerPart(parmax)) + 1;
|
||||
gp_Pnt2d p1,p2;
|
||||
Standard_Real du=0.,dv=0.;
|
||||
p1 = GetPointOnPolygo(Pol,parmin);
|
||||
for (Standard_Integer i=irang1; i <= irang2 && du <= URes && dv <= VRes; i++) {
|
||||
p2 = Pol.Point(i);
|
||||
du += Abs(p2.X()-p1.X());
|
||||
dv += Abs(p2.Y()-p1.Y());
|
||||
p1 = p2;
|
||||
}
|
||||
if (du <= URes && dv <= VRes) {
|
||||
p2 = GetPointOnPolygo(Pol,parmax);
|
||||
du += Abs(p2.X()-p1.X());
|
||||
dv += Abs(p2.Y()-p1.Y());
|
||||
}
|
||||
return du <= URes && dv <= VRes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : PutVertexOnLine
|
||||
//purpose :
|
||||
@@ -467,7 +389,6 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (L)); //-- aucune verification n est
|
||||
Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (L)); //-- faite au cast.
|
||||
Standard_Integer Nbvtx =0;
|
||||
Standard_Integer Nbptlin =0;
|
||||
Standard_Real tolPLin = Surf->UResolution(Precision::Confusion());
|
||||
tolPLin = Max (tolPLin, Surf->VResolution(Precision::Confusion()));
|
||||
tolPLin = Min (tolPLin, Precision::Confusion());
|
||||
@@ -491,12 +412,10 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
if (typL == IntPatch_Walking) {
|
||||
Nbvtx = wlin->NbVertex();
|
||||
PLin.SetWLine(OnFirst,wlin);
|
||||
Nbptlin = wlin->NbPnts();
|
||||
}
|
||||
else if ( typL == IntPatch_Restriction) {
|
||||
Nbvtx = rlin->NbVertex();
|
||||
PLin.SetRLine(OnFirst,rlin);
|
||||
Nbptlin = rlin->NbPnts();
|
||||
}
|
||||
else {
|
||||
throw Standard_DomainError();
|
||||
@@ -553,8 +472,6 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
|
||||
// MSV Oct 15, 2001: use tolerance of this edge if possible
|
||||
Standard_Real edgeTol = Tol3d(arc,Domain,Tol);
|
||||
Standard_Real URes = Surf->UResolution(edgeTol);
|
||||
Standard_Real VRes = Surf->VResolution(edgeTol);
|
||||
|
||||
IntPatch_HInterTool::Bounds(arc,PFirst,PLast);
|
||||
if(Precision::IsNegativeInfinite(PFirst))
|
||||
@@ -567,26 +484,16 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
// return;
|
||||
//}
|
||||
|
||||
Standard_Boolean isVFirst = Standard_False, isVLast = Standard_False;
|
||||
gp_Pnt2d p2dFirst,p2dLast;
|
||||
Standard_Real tolUFirst=0.,tolVFirst=0.,tolULast=0.,tolVLast=0.;
|
||||
Domain->Initialize(arc);
|
||||
for (Domain->InitVertexIterator(); Domain->MoreVertex(); Domain->NextVertex()) {
|
||||
Handle(Adaptor3d_HVertex) vtx = Domain->Vertex();
|
||||
Standard_Real prm = IntPatch_HInterTool::Parameter(vtx,arc);
|
||||
if (Abs(prm - PFirst) < Precision::PConfusion()) {
|
||||
arc->D0(PFirst,p2dFirst);
|
||||
Standard_Real tol3d = Max (Tol3d(vtx,Domain), edgeTol);
|
||||
tolUFirst = Surf->UResolution(tol3d);
|
||||
tolVFirst = Surf->VResolution(tol3d);
|
||||
isVFirst = Standard_True;
|
||||
}
|
||||
else if (Abs(prm - PLast) < Precision::PConfusion()) {
|
||||
arc->D0(PLast,p2dLast);
|
||||
Standard_Real tol3d = Max (edgeTol, Tol3d(vtx,Domain));
|
||||
tolULast = Surf->UResolution(tol3d);
|
||||
tolVLast = Surf->VResolution(tol3d);
|
||||
isVLast = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -697,110 +604,34 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
Commun.Perform(PLin,Brise);
|
||||
locpt.Clear();
|
||||
locpt2.Clear();
|
||||
Standard_Integer Commun_NbSectionPoints = Commun.NbSectionPoints();
|
||||
Standard_Integer Commun_NbTangentZones = Commun.NbTangentZones();
|
||||
Standard_Integer Commun_Section_Tangent = Commun_NbSectionPoints
|
||||
+ Commun_NbTangentZones;
|
||||
for (i=1;i<=Commun_Section_Tangent;i++) {
|
||||
Standard_Real W1[2],W2[2];
|
||||
Standard_Boolean refine[2],useWL[2];
|
||||
Standard_Integer nbpt = 1;
|
||||
if(i<=Commun_NbSectionPoints) {
|
||||
// intersection point
|
||||
W1[0] = Commun.PntValue(i).ParamOnFirst();
|
||||
W2[0] = Commun.PntValue(i).ParamOnSecond();
|
||||
refine[0] = Standard_True;
|
||||
}
|
||||
else {
|
||||
// tangent zone
|
||||
Standard_Real UMinCh,UMaxCh; //-- ligne de cheminement 0..(Nbptlin-1)
|
||||
Standard_Real UMinAr,UMaxAr; //-- polyline of arc 0..(NbEchant-1)
|
||||
Commun.ZoneValue(i-Commun_NbSectionPoints).ParamOnFirst(UMinCh,UMaxCh);
|
||||
Commun.ZoneValue(i-Commun_NbSectionPoints).ParamOnSecond(UMinAr,UMaxAr);
|
||||
gp_Pnt2d p1Ar = GetPointOnPolygo(Brise,UMinAr);
|
||||
gp_Pnt2d p2Ar = GetPointOnPolygo(Brise,UMaxAr);
|
||||
Standard_Real tolU = URes*2.;
|
||||
Standard_Real tolV = VRes*2.;
|
||||
if (isVFirst && ArePnt2dEqual(p1Ar,p2dFirst,tolUFirst,tolVFirst)) {
|
||||
tolU = Max(tolUFirst,tolU); tolV = Max(tolVFirst,tolV);
|
||||
}
|
||||
if (isVLast && ArePnt2dEqual(p2Ar,p2dLast,tolULast,tolVLast)) {
|
||||
tolU = Max(tolULast,tolU); tolV = Max(tolVLast,tolV);
|
||||
}
|
||||
Standard_Real nptCh = UMaxCh-UMinCh;
|
||||
Standard_Boolean isNptLow = (nptCh < 10. && nptCh < Nbptlin/100.) ||
|
||||
(!Domain->Has3d() && Standard_Integer(nptCh)+1 < Nbptlin);
|
||||
if (!isNptLow && !IsSegment2dSmall(Brise,UMinAr,UMaxAr,tolU,tolV)) {
|
||||
// treat both ends
|
||||
Standard_Real UMinChP,UMinArP,UMaxArP;
|
||||
UMinChP = IntegerPart(UMinCh);
|
||||
UMinArP = IntegerPart(UMinAr);
|
||||
UMaxArP = IntegerPart(UMaxAr);
|
||||
Standard_Integer irangAr1,irangAr2;
|
||||
irangAr1 = Standard_Integer(UMinArP)+1;
|
||||
irangAr2 = Standard_Integer(UMaxArP)+1;
|
||||
UMinChP = UMinCh - UMinChP;
|
||||
UMinArP = UMinAr - UMinArP;
|
||||
//UMaxChP = UMaxCh - UMaxChP; UMaxArP = UMaxAr - UMaxArP;
|
||||
const Standard_Real eps = 1e-10;
|
||||
// Standard_Boolean isChExtr1 = irangCh1==1 && UMinChP<eps;
|
||||
// Standard_Boolean isChExtr2 = irangCh2==Nbptlin;
|
||||
Standard_Boolean isArExtr1 = irangAr1==1 && UMinArP<eps;
|
||||
Standard_Boolean isArExtr2 = irangAr2==NbEchant;
|
||||
// detect orientation
|
||||
gp_Pnt2d p1Ch = GetPointOnPolygo(PLin,UMinCh);
|
||||
Standard_Real d11 = p1Ch.SquareDistance(p1Ar);
|
||||
Standard_Real d12 = p1Ch.SquareDistance(p2Ar);
|
||||
Standard_Boolean sameOri = d11 < d12;
|
||||
if (!sameOri) {
|
||||
Standard_Boolean itmp=isArExtr1; isArExtr1=isArExtr2; isArExtr2=itmp;
|
||||
Standard_Real dtmp=UMinAr; UMinAr=UMaxAr; UMaxAr=dtmp;
|
||||
}
|
||||
W1[0] = UMinCh; W1[1] = UMaxCh;
|
||||
W2[0] = UMinAr; W2[1] = UMaxAr;
|
||||
//refine[0] = ! (isChExtr1 || isArExtr1);
|
||||
//refine[1] = ! (isChExtr2 || isArExtr2);
|
||||
refine[0] = refine[1] = Standard_False;
|
||||
useWL[0] = !isArExtr1;
|
||||
useWL[1] = !isArExtr2;
|
||||
nbpt = 2;
|
||||
}
|
||||
else {
|
||||
// treat the middle point as an intersection point
|
||||
W1[0] = 0.5*(UMinCh+UMaxCh);
|
||||
W2[0] = 0.5*(UMinAr+UMaxAr);
|
||||
refine[0] = Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
// We do not need in putting vertex into tangent zone(s).
|
||||
// Therefore, only section points are interested by us.
|
||||
// Boundary of WLine (its first/last points) will be
|
||||
// marked by some vertex later. See bug #29494.
|
||||
const Standard_Integer aNbSectionPts = Commun.NbSectionPoints();
|
||||
for (i = 1; i <= aNbSectionPts; i++)
|
||||
{
|
||||
const Standard_Real aW1 = Commun.PntValue(i).ParamOnFirst(),
|
||||
aW2 = Commun.PntValue(i).ParamOnSecond();
|
||||
|
||||
Standard_Integer nbTreated = 0;
|
||||
for (Standard_Integer ip=0; ip < nbpt; ip++) {
|
||||
GetLinePoint2d (L, W1[ip]+1, !OnFirst, U,V);
|
||||
GetLinePoint2d (L, aW1+1, !OnFirst, U,V);
|
||||
|
||||
if (!refine[ip] && useWL[ip]) {
|
||||
Standard_Real aU1,aV1;
|
||||
GetLinePoint2d (L, W1[ip]+1, OnFirst, aU1,aV1);
|
||||
p2d.SetCoord(aU1,aV1);
|
||||
Standard_Real paramProj;
|
||||
if (!IntPatch_HInterTool::Project(arc,p2d,paramProj,p2d)) continue;
|
||||
W = paramProj;
|
||||
}
|
||||
else {
|
||||
Standard_Real par = IntegerPart(W2[ip]);
|
||||
Standard_Real par = IntegerPart(aW2);
|
||||
Standard_Integer Irang = Standard_Integer(par) + 1;
|
||||
if (Irang == Brise.NbPoints()) {
|
||||
if (Irang == Brise.NbPoints())
|
||||
{
|
||||
Irang--;
|
||||
par = 1.;
|
||||
}
|
||||
else {
|
||||
par =Abs(W2[ip]-par);
|
||||
}
|
||||
W = (1.-par)*Brise.Parameter(Irang) + par*Brise.Parameter(Irang+1);
|
||||
else
|
||||
{
|
||||
par = Abs(aW2 - par);
|
||||
}
|
||||
|
||||
Standard_Boolean refined = Standard_False;
|
||||
if (refine[ip])
|
||||
{
|
||||
W = (1. - par)*Brise.Parameter(Irang) + par*Brise.Parameter(Irang + 1);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//-- On a trouve un point 2d approche Ua,Va intersection de la ligne
|
||||
//-- de cheminement et de la restriction.
|
||||
@@ -809,19 +640,17 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
//--
|
||||
IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
|
||||
// MSV: extend UV bounds to not miss solution near the boundary
|
||||
Standard_Real margCoef = 0.004;
|
||||
const Standard_Real margCoef = 0.004;
|
||||
Standard_Boolean refined = Standard_False;
|
||||
IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
|
||||
if (IntCS.IsDone())
|
||||
{
|
||||
if (!IntCS.IsEmpty())
|
||||
if (IntCS.IsDone() && !IntCS.IsEmpty())
|
||||
{
|
||||
ptsommet = IntCS.Point();
|
||||
IntCS.ParameterOnSurface(U2,V2);
|
||||
gp_Pnt anOldPnt, aNewPnt;
|
||||
OtherSurf->D0(U,V, anOldPnt);
|
||||
OtherSurf->D0(U2,V2, aNewPnt);
|
||||
if (anOldPnt.SquareDistance(aNewPnt) < Precision::Confusion()
|
||||
* Precision::Confusion())
|
||||
if (anOldPnt.SquareDistance(aNewPnt) < Precision::SquareConfusion())
|
||||
{
|
||||
U2 = U;
|
||||
V2 = V;
|
||||
@@ -829,16 +658,8 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
paramarc = IntCS.ParameterOnCurve();
|
||||
refined = Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
U2 = U; V2 = V;
|
||||
paramarc = W;
|
||||
arc->D0(paramarc,p2d);
|
||||
Surf->D0(p2d.X(),p2d.Y(),ptsommet);
|
||||
}
|
||||
|
||||
if (!refine[ip] || refined) {
|
||||
if (refined) {
|
||||
duplicate = Standard_False;
|
||||
for (j=1; j<=locpt.Length();j++) {
|
||||
if (ptsommet.Distance(locpt(j)) <= edgeTol) {
|
||||
@@ -854,7 +675,7 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
}
|
||||
|
||||
if (!duplicate) {
|
||||
Standard_Integer ParamApproxOnLine = Standard_Integer(W1[ip])+1;
|
||||
Standard_Integer ParamApproxOnLine = Standard_Integer(aW1)+1;
|
||||
|
||||
arc->D1(paramarc,p2d,d2d);
|
||||
U1 = p2d.X(); V1 = p2d.Y();
|
||||
@@ -974,14 +795,6 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
else
|
||||
IntSurf::MakeTransition(tgline,tgrst,normsurf,transline,transarc);
|
||||
|
||||
if (typL == IntPatch_Walking && !refine[ip]) {
|
||||
// for new vertex use coordinates from Line
|
||||
if (OnFirst)
|
||||
GetWLinePoint (wlin, paramline, U1,V1,U2,V2,ptsommet);
|
||||
else
|
||||
GetWLinePoint (wlin, paramline, U2,V2,U1,V1,ptsommet);
|
||||
}
|
||||
|
||||
nbTreated++;
|
||||
if (!ivtx) {
|
||||
Sommet.SetValue(ptsommet,vtxTol,Standard_False); // pour tangence
|
||||
@@ -1167,7 +980,6 @@ void IntPatch_RstInt::PutVertexOnLine (const Handle(IntPatch_Line)& L,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nbTreated == 2 && typL == IntPatch_Walking) {
|
||||
// We processed a tangent zone, and both ends have been treated.
|
||||
// So mark WLine as having arc
|
||||
|
@@ -91,20 +91,80 @@ static void FillPointsHash(const Handle(IntPatch_WLine) &theWLine,
|
||||
// Static subfunction in ComputePurgedWLine and DeleteOuter.
|
||||
//=========================================================================
|
||||
static Handle(IntPatch_WLine) MakeNewWLine(const Handle(IntPatch_WLine) &theWLine,
|
||||
const NCollection_Array1<Standard_Integer> &thePointsHash)
|
||||
NCollection_Array1<Standard_Integer> &thePointsHash,
|
||||
const Standard_Boolean theIsOuter)
|
||||
{
|
||||
Standard_Integer i;
|
||||
|
||||
Handle(IntSurf_LineOn2S) aPurgedLineOn2S = new IntSurf_LineOn2S();
|
||||
Handle(IntPatch_WLine) aLocalWLine = new IntPatch_WLine(aPurgedLineOn2S, Standard_False);
|
||||
Standard_Integer anOldLineIdx = 1, aVertexIdx = 1;
|
||||
Standard_Integer anOldLineIdx = 1, aVertexIdx = 1, anIndexPrev = -1, anIdxOld = -1;
|
||||
gp_Pnt aPPrev, aPOld;
|
||||
for(i = 1; i <= thePointsHash.Upper(); i++)
|
||||
{
|
||||
if (thePointsHash(i) == 0)
|
||||
{
|
||||
// Point has to be added
|
||||
|
||||
const gp_Pnt aP = theWLine->Point(i).Value();
|
||||
const Standard_Real aSqDistPrev = aPPrev.SquareDistance(aPOld);
|
||||
const Standard_Real aSqDist = aPPrev.SquareDistance(aP);
|
||||
|
||||
const Standard_Real aRatio = (aSqDistPrev < gp::Resolution()) ? 0.0 : 9.0*aSqDist / aSqDistPrev;
|
||||
|
||||
if(theIsOuter ||
|
||||
(aRatio < gp::Resolution()) ||
|
||||
((1.0 < aRatio) && (aRatio < 81.0)) ||
|
||||
(i - anIndexPrev <= 1) ||
|
||||
(i - anIdxOld <= 1))
|
||||
{
|
||||
// difference in distances is satisfactory
|
||||
// (1/9 < aSqDist/aSqDistPrev < 9)
|
||||
|
||||
// Store this point.
|
||||
aPurgedLineOn2S->Add(theWLine->Point(i));
|
||||
anOldLineIdx++;
|
||||
aPOld = aPPrev;
|
||||
aPPrev = aP;
|
||||
anIdxOld = anIndexPrev;
|
||||
anIndexPrev = i;
|
||||
}
|
||||
else if(aSqDist >= aSqDistPrev*9.0)
|
||||
{
|
||||
// current segment is much more longer
|
||||
// (aSqDist/aSqDistPrev >= 9)
|
||||
|
||||
i = (i + anIndexPrev)/2;
|
||||
thePointsHash(i) = 0;
|
||||
i--;
|
||||
}
|
||||
else
|
||||
{
|
||||
//previous segment is much more longer
|
||||
//(aSqDist/aSqDistPrev <= 1/9)
|
||||
|
||||
if(anIndexPrev - anIdxOld > 1)
|
||||
{
|
||||
//Delete aPPrev from WL
|
||||
aPurgedLineOn2S->RemovePoint(aPurgedLineOn2S->NbPoints());
|
||||
anOldLineIdx--;
|
||||
|
||||
// Insert point between aPOld and aPPrev
|
||||
i = (anIdxOld + anIndexPrev) / 2;
|
||||
thePointsHash(i) = 0;
|
||||
|
||||
aPPrev = aPOld;
|
||||
anIndexPrev = anIdxOld;
|
||||
}
|
||||
else
|
||||
{
|
||||
aPOld = aPPrev;
|
||||
anIdxOld = anIndexPrev;
|
||||
}
|
||||
|
||||
//Next iterations will start from this inserted point.
|
||||
i--;
|
||||
}
|
||||
}
|
||||
else if (thePointsHash(i) == -1)
|
||||
{
|
||||
@@ -113,7 +173,11 @@ static Handle(IntPatch_WLine) MakeNewWLine(const Handle(IntPatch_WLine)
|
||||
aVertex.SetParameter(anOldLineIdx++);
|
||||
aLocalWLine->AddVertex(aVertex);
|
||||
aPurgedLineOn2S->Add(theWLine->Point(i));
|
||||
aPPrev = aPOld = theWLine->Point(i).Value();
|
||||
anIndexPrev = anIdxOld = i;
|
||||
}
|
||||
|
||||
//Other points will be rejected by purger.
|
||||
}
|
||||
|
||||
return aLocalWLine;
|
||||
@@ -241,7 +305,7 @@ static Handle(IntPatch_WLine)
|
||||
}
|
||||
|
||||
// Build new line and modify geometry of necessary vertexes.
|
||||
Handle(IntPatch_WLine) aLocalWLine = MakeNewWLine(theWLine, aDelOuterPointsHash);
|
||||
Handle(IntPatch_WLine) aLocalWLine = MakeNewWLine(theWLine, aDelOuterPointsHash, Standard_True);
|
||||
|
||||
if (aChangedFirst)
|
||||
{
|
||||
@@ -483,7 +547,7 @@ static Handle(IntPatch_WLine)
|
||||
}
|
||||
}
|
||||
|
||||
return MakeNewWLine(theWLine, aNewPointsHash);
|
||||
return MakeNewWLine(theWLine, aNewPointsHash, Standard_False);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1218,8 +1282,7 @@ Handle(IntPatch_WLine) IntPatch_WLineTool::
|
||||
const Handle(Adaptor3d_HSurface) &theS1,
|
||||
const Handle(Adaptor3d_HSurface) &theS2,
|
||||
const Handle(Adaptor3d_TopolTool) &theDom1,
|
||||
const Handle(Adaptor3d_TopolTool) &theDom2,
|
||||
const Standard_Boolean theRestrictLine)
|
||||
const Handle(Adaptor3d_TopolTool) &theDom2)
|
||||
{
|
||||
Standard_Integer i, k, v, nb, nbvtx;
|
||||
Handle(IntPatch_WLine) aResult;
|
||||
@@ -1322,11 +1385,8 @@ Handle(IntPatch_WLine) IntPatch_WLineTool::
|
||||
return aLocalWLine;
|
||||
}
|
||||
|
||||
if (theRestrictLine)
|
||||
{
|
||||
// II: Delete out of borders points.
|
||||
aLocalWLine = DeleteOuterPoints(aLocalWLine, theS1, theS2, theDom1, theDom2);
|
||||
}
|
||||
|
||||
// III: Delete points by tube criteria.
|
||||
Handle(IntPatch_WLine) aLocalWLineTube =
|
||||
|
@@ -34,7 +34,6 @@ public:
|
||||
//!
|
||||
//! II
|
||||
//! Removes point out of borders in case of non periodic surfaces.
|
||||
//! This step is done only if theRestrictLine is true.
|
||||
//!
|
||||
//! III
|
||||
//! Removes exceed points using tube criteria:
|
||||
@@ -48,8 +47,7 @@ public:
|
||||
const Handle(Adaptor3d_HSurface) &theS1,
|
||||
const Handle(Adaptor3d_HSurface) &theS2,
|
||||
const Handle(Adaptor3d_TopolTool) &theDom1,
|
||||
const Handle(Adaptor3d_TopolTool) &theDom2,
|
||||
const Standard_Boolean theRestrictLine);
|
||||
const Handle(Adaptor3d_TopolTool) &theDom2);
|
||||
|
||||
//! Joins all WLines from theSlin to one if it is possible and records
|
||||
//! the result into theSlin again. Lines will be kept to be splitted if:
|
||||
|
@@ -358,8 +358,6 @@ static Standard_Boolean isTreatAnalityc(const BRepAdaptor_Surface& theBAS1,
|
||||
void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
|
||||
const TopoDS_Face& aF2)
|
||||
{
|
||||
Standard_Boolean RestrictLine = Standard_False;
|
||||
|
||||
if (myContext.IsNull()) {
|
||||
myContext=new IntTools_Context;
|
||||
}
|
||||
@@ -509,14 +507,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
|
||||
myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
|
||||
}
|
||||
|
||||
if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) ||
|
||||
(myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
|
||||
(myHS2->IsUClosed() && !myHS2->IsUPeriodic()) ||
|
||||
(myHS2->IsVClosed() && !myHS2->IsVPeriodic()))
|
||||
{
|
||||
RestrictLine = Standard_True;
|
||||
}
|
||||
//
|
||||
if((aType1 != GeomAbs_BSplineSurface) &&
|
||||
(aType1 != GeomAbs_BezierSurface) &&
|
||||
(aType1 != GeomAbs_OtherSurface) &&
|
||||
@@ -524,8 +514,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
|
||||
(aType2 != GeomAbs_BezierSurface) &&
|
||||
(aType2 != GeomAbs_OtherSurface))
|
||||
{
|
||||
RestrictLine = Standard_True;
|
||||
|
||||
if ((aType1 == GeomAbs_Torus) ||
|
||||
(aType2 == GeomAbs_Torus))
|
||||
{
|
||||
@@ -533,27 +521,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if(!RestrictLine)
|
||||
{
|
||||
TopExp_Explorer aExp;
|
||||
for(Standard_Integer i = 0; (!RestrictLine) && (i < 2); i++)
|
||||
{
|
||||
const TopoDS_Face& aF=(!i) ? myFace1 : myFace2;
|
||||
aExp.Init(aF, TopAbs_EDGE);
|
||||
for(; aExp.More(); aExp.Next())
|
||||
{
|
||||
const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
|
||||
|
||||
if(BRep_Tool::Degenerated(aE))
|
||||
{
|
||||
RestrictLine = Standard_True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INTTOOLS_FACEFACE_DEBUG
|
||||
if(!myListOfPnts.IsEmpty()) {
|
||||
char aBuff[10000];
|
||||
@@ -581,7 +548,7 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
|
||||
myIntersector.Perform(myHS1, dom1, TolArc, TolTang);
|
||||
else
|
||||
myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang,
|
||||
myListOfPnts, RestrictLine, isGeomInt);
|
||||
myListOfPnts, isGeomInt);
|
||||
|
||||
myIsDone = myIntersector.IsDone();
|
||||
|
||||
@@ -592,10 +559,6 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
|
||||
return;
|
||||
}
|
||||
//
|
||||
if(RestrictLine) {
|
||||
myListOfPnts.Clear(); // to use LineConstructor
|
||||
}
|
||||
//
|
||||
const Standard_Integer aNbLinIntersector = myIntersector.NbLines();
|
||||
for (Standard_Integer i=1; i <= aNbLinIntersector; ++i) {
|
||||
MakeCurve(i, dom1, dom2, TolArc);
|
||||
|
@@ -246,7 +246,22 @@ void IntTools_TopolTool::ComputeSamplePoints()
|
||||
}
|
||||
if(nbsu < 10) nbsu = 10;
|
||||
if(nbsv < 10) nbsv = 10;
|
||||
// Check anisotropy
|
||||
Standard_Real anULen = (usup - uinf) / myS->UResolution(1.);
|
||||
Standard_Real anVLen = (vsup - vinf) / myS->VResolution(1.);
|
||||
Standard_Real aRatio = anULen / anVLen;
|
||||
if (aRatio >= 10.)
|
||||
{
|
||||
nbsu *= 2;
|
||||
nbsu = Min(nbsu, aMaxNbSample);
|
||||
}
|
||||
else if (aRatio <= 0.1)
|
||||
{
|
||||
nbsv *= 2;
|
||||
nbsv = Min(nbsv, aMaxNbSample);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case GeomAbs_SurfaceOfExtrusion: {
|
||||
nbsu = 15;
|
||||
|
@@ -2361,8 +2361,17 @@ SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
|
||||
{
|
||||
aP1.SetXYZ(line->Value(aPInd).Value().XYZ());
|
||||
if (aP1.SquareDistance(aPInt) > Precision::SquareConfusion())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (aPInd == 1)
|
||||
{
|
||||
// After insertion, we will obtain
|
||||
// two coincident points in the line.
|
||||
// Therefore, insertion is forbidden.
|
||||
return isOK;
|
||||
}
|
||||
}
|
||||
|
||||
for (++aPInd; aPInd <= aNbPnts; aPInd++)
|
||||
{
|
||||
@@ -2402,8 +2411,17 @@ SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1,
|
||||
{
|
||||
aPCurr.SetXYZ(line->Value(aPInd).Value().XYZ());
|
||||
if (aPCurr.SquareDistance(aPInt) > Precision::SquareConfusion())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (aPInd == aNbPnts)
|
||||
{
|
||||
// After insertion, we will obtain
|
||||
// two coincident points in the line.
|
||||
// Therefore, insertion is forbidden.
|
||||
return isOK;
|
||||
}
|
||||
}
|
||||
|
||||
for (--aPInd; aPInd > 0; aPInd--)
|
||||
{
|
||||
|
@@ -887,7 +887,7 @@ Standard_Boolean LocOpe_SplitShape::AddOpenWire(const TopoDS_Wire& W,
|
||||
aLocalFace = FaceRef.Oriented(wfirst.Orientation());
|
||||
GetDirection(LastEdge, TopoDS::Face(aLocalFace),plast , dlast, Standard_False);
|
||||
|
||||
Standard_Boolean cond;
|
||||
Standard_Boolean cond = Standard_True;
|
||||
|
||||
if(IsPeriodic) {
|
||||
|
||||
@@ -1524,6 +1524,8 @@ Standard_Boolean ChoixUV(const TopoDS_Edge& Last,
|
||||
TopoDS_Edge anEdge = TopoDS::Edge (Poss.FindKey (index));
|
||||
|
||||
GetDirection(anEdge, F, p2d, v2d, Standard_True);
|
||||
if(!SameUV(plst,p2d,surf))
|
||||
continue;
|
||||
|
||||
surf.D0 (p2d.X(), p2d.Y(), aPCur);
|
||||
|
||||
|
@@ -533,6 +533,9 @@ Standard_Boolean Project(const TopoDS_Vertex& V,
|
||||
|
||||
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
|
||||
|
||||
Standard_Real aUmin, aUmax, aVmin, aVmax;
|
||||
ShapeAnalysis::GetFaceUVBounds(F, aUmin, aUmax, aVmin, aVmax);
|
||||
|
||||
if (theEdge.IsNull())
|
||||
{
|
||||
gp_Pnt toproj(BRep_Tool::Pnt(V));
|
||||
@@ -618,11 +621,14 @@ Standard_Boolean Project(const TopoDS_Vertex& V,
|
||||
if (dumin > dumax && adSurf.IsUPeriodic())
|
||||
{
|
||||
Standard_Real aX1 = aPBound2d.X();
|
||||
Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aX1, adSurf.FirstUParameter(), adSurf.LastUParameter());
|
||||
Standard_Real aShift = ShapeAnalysis::AdjustByPeriod(aX1, (aUmin + aUmax) *0.5, adSurf.LastUParameter() - adSurf.FirstUParameter());
|
||||
//Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aX1, adSurf.FirstUParameter(), adSurf.LastUParameter());
|
||||
aX1 += aShift;
|
||||
aPBound2d.SetX(aX1);
|
||||
Standard_Real aX2 = p2d.X();
|
||||
aShift = ShapeAnalysis::AdjustToPeriod(aX2, adSurf.FirstUParameter(), adSurf.LastUParameter());
|
||||
aShift = ShapeAnalysis::AdjustByPeriod(aX2, (aUmin + aUmax) *0.5, adSurf.LastUParameter() - adSurf.FirstUParameter());
|
||||
|
||||
//aShift = ShapeAnalysis::AdjustToPeriod(aX2, adSurf.FirstUParameter(), adSurf.LastUParameter());
|
||||
aX2 += aShift;
|
||||
dumin = Abs(aX2 - aX1);
|
||||
if (dumin > dumax && (Abs(dumin - adSurf.UPeriod()) < Precision::PConfusion()) )
|
||||
@@ -637,11 +643,14 @@ Standard_Boolean Project(const TopoDS_Vertex& V,
|
||||
if (dvmin > dvmax && adSurf.IsVPeriodic())
|
||||
{
|
||||
Standard_Real aY1 = aPBound2d.Y();
|
||||
Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aY1, adSurf.FirstVParameter(), adSurf.LastVParameter());
|
||||
Standard_Real aShift = ShapeAnalysis::AdjustByPeriod(aY1, (aVmin + aVmax) *0.5, adSurf.LastVParameter() - adSurf.FirstVParameter());
|
||||
//Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aY1, adSurf.FirstVParameter(), adSurf.LastVParameter());
|
||||
aY1 += aShift;
|
||||
aPBound2d.SetY(aY1);
|
||||
Standard_Real aY2 = p2d.Y();
|
||||
aShift = ShapeAnalysis::AdjustToPeriod(aY2, adSurf.FirstVParameter(), adSurf.LastVParameter());
|
||||
|
||||
aShift = ShapeAnalysis::AdjustByPeriod(aY2, (aVmin + aVmax) *0.5, adSurf.LastVParameter() - adSurf.FirstVParameter());
|
||||
/*aShift = ShapeAnalysis::AdjustToPeriod(aY2, adSurf.FirstVParameter(), adSurf.LastVParameter());*/
|
||||
aY2 += aShift;
|
||||
dvmin = Abs(aY1 - aY2);
|
||||
if (dvmin > dvmax && ( Abs(dvmin - adSurf.VPeriod()) < Precision::Confusion()) )
|
||||
|
@@ -80,6 +80,7 @@
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_MapIteratorOfMapOfShape.hxx>
|
||||
#include <Draw_ProgressIndicator.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
//epa Memory leaks test
|
||||
@@ -195,7 +196,11 @@ options:\n\
|
||||
aMeshParams.ControlSurfaceDeflection = isControlSurDef;
|
||||
aMeshParams.AdaptiveMin = isAdaptiveMin;
|
||||
|
||||
BRepMesh_IncrementalMesh aMesher (aShape, aMeshParams);
|
||||
Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
|
||||
BRepMesh_IncrementalMesh aMesher;
|
||||
aMesher.SetShape (aShape);
|
||||
aMesher.ChangeParameters() = aMeshParams;
|
||||
aMesher.Perform (aProgress);
|
||||
|
||||
di << "Meshing statuses: ";
|
||||
Standard_Integer statusFlags = aMesher.GetStatusFlags();
|
||||
@@ -206,7 +211,7 @@ options:\n\
|
||||
else
|
||||
{
|
||||
Standard_Integer i;
|
||||
for( i = 0; i < 4; i++ )
|
||||
for( i = 0; i < 5; i++ )
|
||||
{
|
||||
if( (statusFlags >> i) & (Standard_Integer)1 )
|
||||
{
|
||||
@@ -224,6 +229,9 @@ options:\n\
|
||||
case 4:
|
||||
di << "ReMesh ";
|
||||
break;
|
||||
case 5:
|
||||
di << "UserBreak";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ public:
|
||||
//! STL-compliant typedef for key type
|
||||
typedef TheKeyType key_type;
|
||||
|
||||
private:
|
||||
protected:
|
||||
// **************** Adaptation of the TListNode to the INDEXEDmap
|
||||
class IndexedMapNode : public NCollection_TListNode<TheKeyType>
|
||||
{
|
||||
|
@@ -13,6 +13,10 @@ OpenGl_AspectMarker.cxx
|
||||
OpenGl_AspectMarker.hxx
|
||||
OpenGl_AspectText.cxx
|
||||
OpenGl_AspectText.hxx
|
||||
OpenGl_FrameStats.cxx
|
||||
OpenGl_FrameStats.hxx
|
||||
OpenGl_FrameStatsPrs.cxx
|
||||
OpenGl_FrameStatsPrs.hxx
|
||||
OpenGl_Group.hxx
|
||||
OpenGl_Group.cxx
|
||||
OpenGl_Structure.hxx
|
||||
|
@@ -63,6 +63,9 @@ public:
|
||||
//! Returns the structure corresponding to the given ID.
|
||||
const OpenGl_Structure* GetStructureById (Standard_Integer theId);
|
||||
|
||||
//! Access directly a collection of structures.
|
||||
const NCollection_IndexedMap<const OpenGl_Structure*>& Structures() const { return myStructs; }
|
||||
|
||||
private:
|
||||
|
||||
NCollection_IndexedMap<const OpenGl_Structure*> myStructs; //!< Indexed map of structures.
|
||||
|
@@ -69,6 +69,9 @@ public:
|
||||
//! Returns the structure corresponding to the given ID.
|
||||
const OpenGl_Structure* GetStructureById (Standard_Integer theId);
|
||||
|
||||
//! Access directly a collection of structures.
|
||||
const NCollection_IndexedMap<const OpenGl_Structure*>& Structures() const { return myStructs; }
|
||||
|
||||
//! Marks object state as outdated (needs BVH rebuilding).
|
||||
void MarkDirty()
|
||||
{
|
||||
|
@@ -24,7 +24,9 @@
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector()
|
||||
: myIsProjectionParallel (Standard_True)
|
||||
: myIsProjectionParallel (Standard_True),
|
||||
myCamScaleInv (1.0),
|
||||
myPixelSize (1.0)
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -44,6 +46,8 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
|
||||
myProjectionMat = theCamera->ProjectionMatrix();
|
||||
myWorldViewMat = theCamera->OrientationMatrix();
|
||||
myWorldViewProjState = theCamera->WorldViewProjState();
|
||||
myCamEye.SetValues (theCamera->Eye().X(), theCamera->Eye().Y(), theCamera->Eye().Z());
|
||||
myCamScaleInv = 1.0 / myCamera->Scale();
|
||||
|
||||
Standard_Real nLeft = 0.0, nRight = 0.0, nTop = 0.0, nBottom = 0.0;
|
||||
Standard_Real fLeft = 0.0, fRight = 0.0, fTop = 0.0, fBottom = 0.0;
|
||||
@@ -124,11 +128,14 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
|
||||
// function : SetViewportSize
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::SetViewportSize (const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight)
|
||||
void OpenGl_BVHTreeSelector::SetViewportSize (Standard_Integer theViewportWidth,
|
||||
Standard_Integer theViewportHeight,
|
||||
Standard_Real theResolutionRatio)
|
||||
{
|
||||
myViewportHeight = theViewportHeight;
|
||||
myViewportWidth = theViewportWidth;
|
||||
myPixelSize = Max (theResolutionRatio / theViewportHeight,
|
||||
theResolutionRatio / theViewportWidth);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -153,10 +160,40 @@ Standard_Real OpenGl_BVHTreeSelector::SignedPlanePointDistance (const OpenGl_Vec
|
||||
return aD + (anA * thePnt.x() + aB * thePnt.y() + aC * thePnt.z());
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCullingDistance
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::SetCullingDistance (CullingContext& theCtx,
|
||||
Standard_Real theDistance) const
|
||||
{
|
||||
theCtx.DistCull = -1.0;
|
||||
if (!myIsProjectionParallel)
|
||||
{
|
||||
theCtx.DistCull = theDistance > 0.0 && !Precision::IsInfinite (theDistance)
|
||||
? theDistance
|
||||
: -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCullingSize
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::SetCullingSize (CullingContext& theCtx,
|
||||
Standard_Real theSize) const
|
||||
{
|
||||
theCtx.SizeCull2 = -1.0;
|
||||
if (theSize > 0.0 && !Precision::IsInfinite (theSize))
|
||||
{
|
||||
theCtx.SizeCull2 = (myPixelSize * theSize) / myCamScaleInv;
|
||||
theCtx.SizeCull2 *= theCtx.SizeCull2;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : CacheClipPtsProjections
|
||||
// purpose : Caches view volume's vertices projections along its normals and AABBs dimensions
|
||||
// Must be called at the beginning of each BVH tree traverse loop
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
|
||||
{
|
||||
@@ -196,63 +233,3 @@ void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
|
||||
myMinOrthoProjectionPts[aDim] = aMinProj;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Intersect
|
||||
// purpose : Detects if AABB overlaps view volume using separating axis theorem (SAT)
|
||||
// =======================================================================
|
||||
Standard_Boolean OpenGl_BVHTreeSelector::Intersect (const OpenGl_Vec3d& theMinPt,
|
||||
const OpenGl_Vec3d& theMaxPt) const
|
||||
{
|
||||
// E1
|
||||
// |_ E0
|
||||
// /
|
||||
// E2
|
||||
|
||||
// E0 test
|
||||
if (theMinPt.x() > myMaxOrthoProjectionPts[0]
|
||||
|| theMaxPt.x() < myMinOrthoProjectionPts[0])
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// E1 test
|
||||
if (theMinPt.y() > myMaxOrthoProjectionPts[1]
|
||||
|| theMaxPt.y() < myMinOrthoProjectionPts[1])
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// E2 test
|
||||
if (theMinPt.z() > myMaxOrthoProjectionPts[2]
|
||||
|| theMaxPt.z() < myMinOrthoProjectionPts[2])
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Standard_Real aBoxProjMax = 0.0, aBoxProjMin = 0.0;
|
||||
const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
|
||||
for (Standard_Integer aPlaneIter = 0; aPlaneIter < 5; aPlaneIter += anIncFactor)
|
||||
{
|
||||
OpenGl_Vec4d aPlane = myClipPlanes[aPlaneIter];
|
||||
aBoxProjMax = (aPlane.x() > 0.0 ? (aPlane.x() * theMaxPt.x()) : aPlane.x() * theMinPt.x())
|
||||
+ (aPlane.y() > 0.0 ? (aPlane.y() * theMaxPt.y()) : aPlane.y() * theMinPt.y())
|
||||
+ (aPlane.z() > 0.0 ? (aPlane.z() * theMaxPt.z()) : aPlane.z() * theMinPt.z());
|
||||
if (aBoxProjMax > myMinClipProjectionPts[aPlaneIter]
|
||||
&& aBoxProjMax < myMaxClipProjectionPts[aPlaneIter])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aBoxProjMin = (aPlane.x() < 0.0 ? aPlane.x() * theMaxPt.x() : aPlane.x() * theMinPt.x())
|
||||
+ (aPlane.y() < 0.0 ? aPlane.y() * theMaxPt.y() : aPlane.y() * theMinPt.y())
|
||||
+ (aPlane.z() < 0.0 ? aPlane.z() * theMaxPt.z() : aPlane.z() * theMinPt.z());
|
||||
if (aBoxProjMin > myMaxClipProjectionPts[aPlaneIter]
|
||||
|| aBoxProjMax < myMinClipProjectionPts[aPlaneIter])
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
@@ -25,6 +25,16 @@
|
||||
//! view volume.
|
||||
class OpenGl_BVHTreeSelector
|
||||
{
|
||||
public:
|
||||
//! Auxiliary structure holding non-persistent culling options.
|
||||
struct CullingContext
|
||||
{
|
||||
Standard_Real DistCull; //!< culling distance
|
||||
Standard_Real SizeCull2; //!< squared culling size
|
||||
|
||||
//! Empty constructor.
|
||||
CullingContext() : DistCull (-1.0), SizeCull2 (-1.0) {}
|
||||
};
|
||||
public:
|
||||
|
||||
//! Creates an empty selector object with parallel projection type by default.
|
||||
@@ -33,19 +43,36 @@ public:
|
||||
//! Retrieves view volume's planes equations and its vertices from projection and world-view matrices.
|
||||
Standard_EXPORT void SetViewVolume (const Handle(Graphic3d_Camera)& theCamera);
|
||||
|
||||
Standard_EXPORT void SetViewportSize (const Standard_Integer theViewportWidth, const Standard_Integer theViewportHeight);
|
||||
Standard_EXPORT void SetViewportSize (Standard_Integer theViewportWidth,
|
||||
Standard_Integer theViewportHeight,
|
||||
Standard_Real theResolutionRatio);
|
||||
|
||||
//! Detects if AABB overlaps view volume using separating axis theorem (SAT).
|
||||
//! @param theMinPt [in] maximum point of AABB.
|
||||
//! @param theMaxPt [in] minimum point of AABB.
|
||||
//! @return Standard_True, if AABB is in viewing area, Standard_False otherwise.
|
||||
Standard_EXPORT Standard_Boolean Intersect (const OpenGl_Vec3d& theMinPt,
|
||||
const OpenGl_Vec3d& theMaxPt) const;
|
||||
//! Setup distance culling.
|
||||
Standard_EXPORT void SetCullingDistance (CullingContext& theCtx,
|
||||
Standard_Real theDistance) const;
|
||||
|
||||
//! Setup size culling.
|
||||
Standard_EXPORT void SetCullingSize (CullingContext& theCtx,
|
||||
Standard_Real theSize) const;
|
||||
|
||||
//! Caches view volume's vertices projections along its normals and AABBs dimensions.
|
||||
//! Must be called at the beginning of each BVH tree traverse loop.
|
||||
Standard_EXPORT void CacheClipPtsProjections();
|
||||
|
||||
//! Checks whether given AABB should be entirely culled or not.
|
||||
//! @param theCtx [in] culling properties
|
||||
//! @param theMinPt [in] maximum point of AABB
|
||||
//! @param theMaxPt [in] minimum point of AABB
|
||||
//! @return Standard_True, if AABB is in viewing area, Standard_False otherwise
|
||||
bool IsCulled (const CullingContext& theCtx,
|
||||
const OpenGl_Vec3d& theMinPt,
|
||||
const OpenGl_Vec3d& theMaxPt) const
|
||||
{
|
||||
return isFullOut (theMinPt, theMaxPt)
|
||||
|| isTooDistant(theCtx, theMinPt, theMaxPt)
|
||||
|| isTooSmall (theCtx, theMinPt, theMaxPt);
|
||||
}
|
||||
|
||||
//! Return the camera definition.
|
||||
const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
|
||||
|
||||
@@ -85,6 +112,93 @@ protected:
|
||||
Standard_EXPORT Standard_Real SignedPlanePointDistance (const OpenGl_Vec4d& theNormal,
|
||||
const OpenGl_Vec4d& thePnt);
|
||||
|
||||
//! Detects if AABB overlaps view volume using separating axis theorem (SAT).
|
||||
//! @param theMinPt [in] maximum point of AABB.
|
||||
//! @param theMaxPt [in] minimum point of AABB.
|
||||
//! @return FALSE, if AABB is in viewing area, TRUE otherwise.
|
||||
bool isFullOut (const OpenGl_Vec3d& theMinPt,
|
||||
const OpenGl_Vec3d& theMaxPt) const
|
||||
{
|
||||
// E1
|
||||
// |_ E0
|
||||
// /
|
||||
// E2
|
||||
|
||||
// E0 test
|
||||
if (theMinPt.x() > myMaxOrthoProjectionPts[0]
|
||||
|| theMaxPt.x() < myMinOrthoProjectionPts[0])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// E1 test
|
||||
if (theMinPt.y() > myMaxOrthoProjectionPts[1]
|
||||
|| theMaxPt.y() < myMinOrthoProjectionPts[1])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// E2 test
|
||||
if (theMinPt.z() > myMaxOrthoProjectionPts[2]
|
||||
|| theMaxPt.z() < myMinOrthoProjectionPts[2])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Standard_Real aBoxProjMax = 0.0, aBoxProjMin = 0.0;
|
||||
const Standard_Integer anIncFactor = myIsProjectionParallel ? 2 : 1;
|
||||
for (Standard_Integer aPlaneIter = 0; aPlaneIter < 5; aPlaneIter += anIncFactor)
|
||||
{
|
||||
OpenGl_Vec4d aPlane = myClipPlanes[aPlaneIter];
|
||||
aBoxProjMax = (aPlane.x() > 0.0 ? (aPlane.x() * theMaxPt.x()) : aPlane.x() * theMinPt.x())
|
||||
+ (aPlane.y() > 0.0 ? (aPlane.y() * theMaxPt.y()) : aPlane.y() * theMinPt.y())
|
||||
+ (aPlane.z() > 0.0 ? (aPlane.z() * theMaxPt.z()) : aPlane.z() * theMinPt.z());
|
||||
if (aBoxProjMax > myMinClipProjectionPts[aPlaneIter]
|
||||
&& aBoxProjMax < myMaxClipProjectionPts[aPlaneIter])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
aBoxProjMin = (aPlane.x() < 0.0 ? aPlane.x() * theMaxPt.x() : aPlane.x() * theMinPt.x())
|
||||
+ (aPlane.y() < 0.0 ? aPlane.y() * theMaxPt.y() : aPlane.y() * theMinPt.y())
|
||||
+ (aPlane.z() < 0.0 ? aPlane.z() * theMaxPt.z() : aPlane.z() * theMinPt.z());
|
||||
if (aBoxProjMin > myMaxClipProjectionPts[aPlaneIter]
|
||||
|| aBoxProjMax < myMinClipProjectionPts[aPlaneIter])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! Returns TRUE if given AABB should be discarded by distance culling criterion.
|
||||
bool isTooDistant (const CullingContext& theCtx,
|
||||
const OpenGl_Vec3d& theMinPt,
|
||||
const OpenGl_Vec3d& theMaxPt) const
|
||||
{
|
||||
if (theCtx.DistCull <= 0.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// check distance to the bounding sphere as fast approximation
|
||||
const Graphic3d_Vec3d aSphereCenter = (theMinPt + theMaxPt) * 0.5;
|
||||
const Standard_Real aSphereRadius = (theMaxPt - theMinPt).maxComp() * 0.5;
|
||||
return (aSphereCenter - myCamEye).Modulus() - aSphereRadius > theCtx.DistCull;
|
||||
}
|
||||
|
||||
//! Returns TRUE if given AABB should be discarded by size culling criterion.
|
||||
bool isTooSmall (const CullingContext& theCtx,
|
||||
const OpenGl_Vec3d& theMinPt,
|
||||
const OpenGl_Vec3d& theMaxPt) const
|
||||
{
|
||||
if (theCtx.SizeCull2 <= 0.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (theMaxPt - theMinPt).SquareModulus() < theCtx.SizeCull2;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! Enumerates planes of view volume.
|
||||
@@ -139,6 +253,11 @@ protected:
|
||||
Standard_Integer myViewportHeight;
|
||||
|
||||
Graphic3d_WorldViewProjState myWorldViewProjState; //!< State of world view projection matrices.
|
||||
|
||||
Graphic3d_Vec3d myCamEye; //!< camera eye position for distance culling
|
||||
Standard_Real myCamScaleInv; //!< inverted camera scale for size culling
|
||||
Standard_Real myPixelSize; //!< pixel size for size culling
|
||||
|
||||
};
|
||||
|
||||
#endif // _OpenGl_BVHTreeSelector_HeaderFile
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user