1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

Compare commits

...

53 Commits

Author SHA1 Message Date
akaftasev
2ab2295cec 0025113: Added progress indicator to BRepMesh_IncrementalMesh [backport for OCCT 7.2.0] 2020-09-23 22:10:49 +03:00
gka
84dd587638 Issue #322 Fix 2020-09-23 20:18:08 +03:00
osa
28c0c6b155 0031773: Visualization - add Prs3d_ToolTorus
Added Prs3d_ToolTorus tool to create a torus
2020-09-23 20:18:08 +03:00
osa
47b0f294be 0031758: Visualization, AIS_InteractiveContext - unify clearDynamicHighlight() method 2020-09-23 20:18:08 +03:00
mzernova
7d6be4672b 0031733: Visualization, Prs3d_ToolQuadric - create indexed arrays
Prs3d_ToolQuadric has been modified to return an indexed triangulation.
Added methods Prs3d_ToolQuadric::CreateTriangulation() and Prs3d_ToolQuadric::CreateTriangulation()
as more straightforward API returning generated triangulation.
Added missing const to constant methods.

Confusing method Prs3d_ToolQuadric::FillArray() filling both
Graphic3d_ArrayOfTriangles and Poly_Triangulation at once has been marked deprecated.

V3d_Trihedron and AIS_Manipulator
now set Closed flag to groups with shaded sphere and arrows.
2020-09-23 20:18:08 +03:00
osa
b453701e1f Visualization, PrsMgr_Presentation - remove graphic structure before nullify [OCCT 7.2.0 backport] 2020-09-23 20:18:08 +03:00
osa
c23d6ec61f 0031715: Visualization, OpenGl_ShaderProgram - add access to proxy shader program.
Back porting of setting unique ID for shader program used to manage resource in graphic driver.
2020-09-23 20:18:08 +03:00
gka
b05ff75a60 0031718: Large tolerance of vertex of the result after split attached shape with an attached contour
Corrected computation of tolerance of vertex for periodic surfaces LocOpe_WiresOnShape in the method Project
2020-09-23 20:18:07 +03:00
emv
e49dc1e054 0031662: Modeling Algorithms - Incomplete result of section operation
BOPAlgo_PaveFiller: Add method for forced Edge/Face intersection to look for additional cases of coincidence.
BOPAlgo_BuilderSolid: Avoid creating solids from unclassified faces as such solids will be useless. Just warn user about unclassified faces.
2020-09-23 20:18:07 +03:00
ifv
abca9f3eb8 0031697: Foundation Classes - Expr_GeneralExpression::Derivative does not seem to work (691 & 720) 2020-09-23 20:18:07 +03:00
kgv
68556f75f9 0031698: Visualization, Graphic3d_Aspects - provide stipple line factor parameter [OCCT 7.2.0 backport]
Added Graphic3d_AspectLine3d::LineStippleFactor() property.
Added -stippleFactor argument to vaspects command.
2020-08-06 13:31:03 +03:00
kgv
3d607bc062 0029346: Visualization, TKOpenGl - collect frame statistics [backported,
partially disabled; fixed frustum culling bug].

Graphic3d_RenderingParams::ToShowStats - new option displaying rendering statistics.

OpenGl_FrameStats - new class for accumulating frame statistics.
OpenGl_Context::FrameStats() provides an access to the frame stats
used for currently rendered context.
OpenGl_View::Redraw() and OpenGl_View::RedrawImmediate()
resets counters within OpenGl_Context::FrameStats().

OpenGl_Layer::UpdateCulling() - simplified resetting of culling state for cullable structures.

# Conflicts:
#	src/OpenGl/OpenGl_FrameBuffer.cxx
2020-07-15 16:09:42 +03:00
kgv
365585ddfb 0028760: Visualization, TKOpenGl - avoid excessive frustum culling traverse within extra OIT rendering pass
Culling traverse is no more called implicitly within OpenGl_Layer::Render().
Instead, all layers are traversed at onces within OpenGl_View::render() beforehand.

OpenGl_BVHTreeSelector methods have been renamed to better reflect their meaning.
Non-persistent culling options has been moved to dedicated structure OpenGl_BVHTreeSelector::CullingContext
so that OpenGl_BVHTreeSelector instance can be used for different Layers without modifying its state.
2020-07-15 16:09:42 +03:00
kgv
c89ab82e4c 0029300: Visualization, TKOpenGl - provide depth pre-pass option
OpenGl_LayerList::Render() now handles new option Graphic3d_RenderingParams::ToEnableDepthPrepass
which prepends additional pass to rendering pipeline filling Depth Buffer in advance.
2020-07-15 16:09:42 +03:00
kgv
cc964ef4d3 0029295: Visualization, TKOpenGl - provide distance culling option
Graphic3d_ZLayerSettings::CullingDistance() and ::CullingSize() - added
new properties configuring culling of small and distant objects, disabled by default.
OpenGl_BVHTreeSelector now handles size culling and distance culling in addition to frustom culling.
2020-07-15 16:09:41 +03:00
ifv
cb127824b2 0031616: Modeling algorithm - Section between two shells returns wire with gaps (720) 2020-07-15 16:09:41 +03:00
ifv
fbebf6078c 0031611: BRepOffsetAPI_NormalProjection - can't build wire in 720 but it was possible in 691 2020-07-15 16:09:41 +03:00
jgv
762fa70875 Fix the case SENR-22-003 "HLR - Different result between 691 and 720" 2020-02-17 14:32:57 +03:00
gka
4dd6fb9a80 # 257 Error in D1 calculation using BRepAdaptor_CompCurve using the last parameter. In OCCT7
Modifications from archive "patch_720_new.7z"
2020-02-17 13:15:35 +03:00
kgv
70608ec03d 0030706: Visualization - fetch font folder list from fontconfig library on Linux [backport occt720]
vfont command now prints fonts in alphabetical order.

# Conflicts:
#	adm/qmake/OccToolkit.pri
2020-02-17 12:40:48 +03:00
kgv
0842e31d95 0030782: Visualization, Font_FTFont - use predefined fallback fonts for extended Unicode subsets [backported to occt720]
Font_FTFont now uses fallback fonts for characters from unsupported Unicode subsets,
managed by Font_FTFont::ToUseUnicodeSubsetFallback()
and Font_FontMgr::ToUseUnicodeSubsetFallback() option, enabled by default.
The fallback list includes common font families for Chinese, Korean and Japanese languages.

Font_FTFont::RenderGlyph() now supports FT_PIXEL_MODE_MONO input format used by some CJK fonts.
OpenGl_Font::createTexture() now limits single texture size to circa 4096 glyphs.

test/testgrid now expects test scripts being in UTF-8 encoding in sync with "DRAWEXE -f script.tcl".

AIS::InitFaceLength() - fixed usage of uninitialized result.

Font_FTFont::RenderGlyph() backport bitmap
2020-02-17 12:40:48 +03:00
kgv
51204152b9 0030663: Visualization - synthesize italic style for a font having no italic style [backport OCCT720]
Font_FTFont now defines shear transformation to synthesize italic style for fonts having no such style.
Font_FontMgr::FindFont() and command "vfont -find" have been extended with -strict option
to check whether the given font is actually registered or not.
Font_FTFont::Init() - added constructor from memory buffer.
Second Font_FTFont::Init() override has been renamed to Font_FTFont::FindAndInit()
to avoid ambiguity between two similar methods taking full font path and font name as string.

# Conflicts:
#	src/AIS/AIS_Dimension.cxx
#	src/OpenGl/OpenGl_Text.cxx
2020-02-17 12:40:48 +03:00
kgv
d517575214 0030474: Visualization - fallback font is ignored for missing font alias within Font_FontMgr::FindFont() 2020-02-17 12:40:47 +03:00
kgv
99d9eb3933 0030439: Visualization - extend fonts search within Font_FontMgr::FindFont() on Linux
Font_FontMgr has been redesigned to:
- Store fonts in a map instead a list.
- Allow mapping multiple fonts to a single alias.
- Log informative message about usage of non-requested font (fallback).
- Register all font files within standard folders on Linux when "fonts.dir" is not found.
- Prefer specific alias ("serif") as default fallback font instead of arbitrary one in a system.

A couple of obsolete and broken font aliases have been removed;
instead, new aliases of fonts popular on Linux platform have been added.

Font_NameOfFont.hxx has been extended with more neutral aliases
"monospace", "serif", "sans-serif", "cjk" and "korean".

Font_FontAspect enumeration values have been renamed Font_FA_ -> Font_FontAspect_
with old values preserved as alias.

Font_SystemFont has been extended with a list of paths to Font_FontAspect styles,
so that entire Font Family is now defined within a single Font_SystemFont instance.
Non-resizable fonts are now ignored by Font Manager.
2020-02-17 12:40:47 +03:00
skl
a3430df1d4 0025852: Visualization - Font_BRepFont produces bad faces for circled symbols [backported to occt720]
Font_BRepFont now uses a dedicated algorithm for text-to-BRep transformation instead of relying on ShapeFix.
It orders wires based on wire classification, analyzes internal zones and creates a few faces (if needed).
TKService dependency from TKShHealing has been dropped.

Font_BRepFont::buildFaces() backport.
2020-02-17 12:40:47 +03:00
kgv
9f9ac0fb5a 0029225: Visualization - Font_FTFont::AdvanceX() retrieves kerning value for incorrect characters pair
Fixed FT_Get_Kerning misuse within Font_FTFont::AdvanceX()/Font_FTFont::AdvanceY().
Font_FTFont::loadGlyph() has been corrected to not return TRUE
in case if method called with 0 argument second+ time.
2020-02-17 12:40:47 +03:00
anv
e0fd0b8797 0029117: Adding translation of Multileader entity
Scaling of width of glyphs is added om Font_FTFont class.
Font "SimSan" is specified as fallback alias for font "NSimSan" (contains Chinese hieroglyphs).
2020-02-17 12:40:47 +03:00
kgv
09aae06737 0029122: Visualization - improve Font_BRepFont to handle one-line-fonts
Font_SystemFont - added a new property SingleStrokeFont().
Font_BRepFont::renderGlyph() has been extended to not close contours
when flag SingleStrokeFont() has been set.
2020-02-17 12:40:46 +03:00
kgv
eea07c2f60 0030278: Foundation Classes - make IndexedMapNode as protected inside of NCollection_IndexedMap
# Conflicts:
#	src/NCollection/NCollection_IndexedMap.hxx
2020-02-17 12:40:46 +03:00
kgv
9cee51b43b 0031174: Visualization - support user-provided stipple line patterns [occt720 backport] 2020-02-17 12:40:46 +03:00
emv
760a94d050 0031306: Modeling Algorithms - Incomplete result of Cut operation
The problem is fixed by #0029323. Integrating test case only.
2020-01-20 09:32:52 +03:00
nbv
a8375ceaf0 0029323: Intersection algorithm produces the curve with oscillation
Sometimes the algorithm of purging of extra points in the walking line makes enormous difference in distance between two neighbor segments of the line. This badly impacts the quality of approximation result. This patch balances the difference in distances by forbidding deletion of some points.

1. tests/bugs/modalg_6/bug27615

The reason of the correction is explained in the message ~0072580 (see issue #28557).

2. tests/bugs/modalg_7/bug28892*
   tests/bugs/modalg_7/bug28984

The reason of the correction is explained in the message ~0072583 (see issue #28984).
2020-01-20 09:30:08 +03:00
ifv
55374b512e 0031260: Geom2dGcc_Circ2d2TanRad fails in this case (720) 2020-01-17 11:30:50 +03:00
ifv
52a5d7a61d 0031203: SENR-21-037 SenerAlgo_ProjectWire fails when projecting wire to face (691 and 720) 2019-12-03 12:37:36 +03:00
gka
77676f1b6d * 0031140: Draw command "cirtang" raises exception on the parallel curves
To avoid exception for parallel curves because the number of solutions exceeds the size of the reserved array a check has been added that the number of solutions does not exceed the size of the reserved array.
2019-11-07 19:49:16 +03:00
emv
515991ffef 0030869: Modeling Data - BRepAdaptor_CompCurve incorrectly evaluates the boundary points
Problem is solved by #0029430. Integrating test case only.
2019-08-09 07:54:09 +03:00
Benjamin Bihler
3d5d9d2b5e 0029775: Modeling Data - BRepAdaptor_CompCurve Parameterization Is Incorrect
Added wire connectivity requirement to class documentation of
BRepAdaptor_CompCurve.
2019-08-07 08:26:57 +03:00
nbv
51e75dba6c 0029430: [Regression] Curve evaluation at boundary point.
Before the fix, BRepAdaptor_CompCurve considered the input wire to be periodic with period LastParameter()-FirstParameter().
Now, method IsPeriodic will always return FALSE because it is impossible to obtain correspondence between the members of BRepAdaptor_CompCurve class and its periodicity status.
New behavior has been documented in upgrade-guide.
2019-08-07 08:26:55 +03:00
emv
b008680dc0 0030708: Modeling Data - Exception is raised while initializing TopoDS_Iterator with null shape
Added protection from null shapes to TopoDS_Iterator::Initialize method.
2019-05-15 14:09:13 +03:00
ifv
2b5ced28c3 0030647: Geom2dGcc_Circ2d2TanRad not giving all the solutions
Correct choice od number of sampling points is added for Adaptor2d_OffsetCurve
2019-04-16 10:49:26 +03:00
emv
1c4b27600f 0030522: Modeling Algorithms - BRepBuilderAPI_MakeWire produces different wires depending on the order of parameters
The following improvements have been implemented in BRepLib_MakeWire class to make it more reliable:
1. Quit adding edges of a wire into result if the current edges have not been added. Return NotDone status.
2. Allow merging not only bounding vertices (connected to only one edge) but also the middle ones, so the multi-connected vertices may appear in the result.

Test case for the issue.
2019-03-15 12:58:13 +03:00
nbv
214171ff60 0029887: Wrong result of CUT operation due to incorrect point-face classification
Using of input tolerance has been eliminated in Geom2dInt_GInter algorithm called from BRepClass_Intersector::Perform(...) method. Now, the input tolerance is used only for check ON-status of classification.

(cherry picked from commit 748c9dc6ae0d6018018fca585b6d8cf511c0dd0b)
(cherry picked from commit 204e98c0b1)
2018-06-25 10:15:52 +03:00
nbv
22f9125e1e Correction of test cases. 2018-02-15 15:15:29 +03:00
nbv
1a196a871d 0029510: IntWalk_PWalking:: PutToBoundary(...) method results in appearing several coincident points in Walking-line
Places have been detected where coincident points are created. The problem has been fixed.

(cherry picked from commit 7c7cda9f73f8762d4999657a925f65cd02bc6864)
2018-02-15 14:47:12 +03:00
nbv
5eba99e74b 0029494: Intersection line between two parametric surfaces is restricted incorrectly if it matches the surface boundary
Creation of IntPatch_Points is forbidden in tangent-zones exceptionally domain boundaries of intersected surface.

(cherry picked from commit 2123a44c2595633288e208a352050592710782f5)
2018-02-15 10:48:00 +03:00
nbv
1560ac5528 # Correction in test cases and documentation.
(cherry picked from commit b244aa455edc4b973457be365ef95bb475523654)
2018-02-14 14:59:37 +03:00
nbv
4b46072ae9 # Correction of test case
(cherry picked from commit 663b5da04a351f0ba1ffc8b26c7df818ad56545b)
2018-02-14 14:57:29 +03:00
nbv
eed77ff55c 0029496: No intersection curve between faces if starting points are given
Now, bounded IntPatch_Points are found in case when starting points are used in intersection algorithm. Before the fix, these points were not looked for (even).

(cherry picked from commit e6a1e86e7b926937f6773d45ed75a2c36d0e7c27)
2018-02-14 14:55:55 +03:00
emv
118e720920 0029488: Regression: boolean operation " general fuse" creates solid containing 5 not connected shells lying on the one level.
Boolean Operations - when checking two faces with the same bounds on Same Domain, take into account possible deviation of the edges from the faces surfaces.

Test cases for the issue.

(cherry picked from commit 8a7476a622)
2018-02-14 11:47:31 +03:00
gka
80f77ed256 # Modified scripts 2018-02-05 17:27:12 +03:00
emv
8f87d4a954 0029465: Regression relation to 691 version: Extrema_ExtCC returns IsParallel equal to true for not parallel curves
Strengthening of the criteria of the parallel status of the curves by additional checking if the ends of the curves do not diverge.

Test cases for the issue.
2018-02-05 11:20:31 +03:00
gka
eeccb2515d 0029473: DRAW command "splitshape" produces invalid result on the cylindrical face.
Fix for porting SenerAlgo on the OCCT 720.

Test case for the issue.
2018-02-05 11:20:30 +03:00
msv
b1ee6d0e4b 0029463: Regression relation to 691 version: Method BndBox::IsOut() returns true for point lying on the planar face
Correct the method BRepBndLib::Add so that to enlarge the bounding box on the tolerance of edges which curves participate in calculation of the box.
2018-02-05 11:20:08 +03:00
219 changed files with 8822 additions and 3541 deletions

View File

@@ -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()

View File

@@ -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"

View File

@@ -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.

View File

@@ -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
@@ -142,4 +145,4 @@ puts "Animation FPS: $fps_animation"
puts ""
puts "Scene contains [lindex [trinfo c] 3] triangles"
puts ""
puts "Print 'animateSpheres 10.0' to restart animation"
puts "Print 'animateSpheres 10.0' to restart animation"

View File

@@ -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())
{
aSurface = new Geom_OffsetSurface( aSurface, anOffset );
anOffset = 0.0e0;
}
if (AIS::GetPlaneFromFace (theFace, thePlane, theSurface, theSurfaceType, theOffset)
&& Abs (theOffset) > Precision::Confusion())
{
theSurface = new Geom_OffsetSurface (theSurface, theOffset);
theOffset = 0.0e0;
}
}
//=======================================================================

View File

@@ -335,31 +335,31 @@ 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());
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
Font_BRepFont aFont;
if (aFont.FindAndInit (aTextAspect->Aspect()->Font(), aTextAspect->Aspect()->GetTextFontAspect(), aTextAspect->Height(), Font_StrictLevel_Any))
{
Standard_Utf32Char aCurrChar = *anIter;
Standard_Utf32Char aNextChar = *(++anIter);
theWidth += aFont.AdvanceX (aCurrChar, aNextChar);
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
{
Standard_Utf32Char aCurrChar = *anIter;
Standard_Utf32Char aNextChar = *(++anIter);
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);
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
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))
{
Standard_Utf32Char aCurrChar = *anIter;
Standard_Utf32Char aNextChar = *(++anIter);
theWidth += (Standard_Real) aFont->AdvanceX (aCurrChar, aNextChar);
for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; )
{
Standard_Utf32Char aCurrChar = *anIter;
Standard_Utf32Char aNextChar = *(++anIter);
theWidth += (Standard_Real) aFont->AdvanceX (aCurrChar, aNextChar);
}
}
}

View File

@@ -1386,14 +1386,7 @@ protected: //! @name internal methods
if (myLastinMain.IsNull())
return;
if (myLastinMain->IsAutoHilight())
{
myMainPM->ClearImmediateDraw();
}
else
{
myLastinMain->Selectable()->ClearDynamicHighlight (myMainPM);
}
myLastinMain->Selectable()->ClearDynamicHighlight (myMainPM);
}
protected: //! @name internal fields

View File

@@ -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());

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -174,6 +174,8 @@ public:
Standard_EXPORT Handle(Geom2d_BSplineCurve) BSpline() const Standard_OVERRIDE;
Standard_EXPORT Standard_Integer NbSamples() const Standard_OVERRIDE;;

View File

@@ -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

View File

@@ -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

View File

@@ -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";

View File

@@ -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)) {
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) {
// 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;
}
//
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));
}
}
//=======================================================================

View File

@@ -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;
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) {
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();
//
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);
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 {
const Bnd_Box& aBox=aSI.Box();
//
BOPAlgo_ShapeBox& aSB=aVSB.Append1();
aSB.SetShape(aS);
aSB.SetBox(aBox);
else
{
aLFaces.Append(aS);
aShapeBoxMap.Add(aS, aSI.Box());
}
}//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) {
BRep_Builder aBB;
// 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();
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);
}
aItLS.Initialize(aLIF);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aFI=aItLS.Value();
aLFINx.Append(aFI);
}
theInParts.Bind(aSolid, aLFINx);
aLSolids.Append(aSD);
aSolidsIF.Bind(aSD, aLIF);
aShapeBoxMap.Add(aSD, aBoxS);
aDraftSolid.Add(aS, aSD);
}
// 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;
}
//
if (aNbFIN || bHasImage) {
theDraftSolids.Bind(aSolid, aSDraft);
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());
}
}
}

View File

@@ -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()) {

View File

@@ -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:

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;
}
//=======================================================================

View File

@@ -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;

View File

@@ -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;

View File

@@ -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));
}

View File

@@ -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,27 +42,28 @@ BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
myFace(F),
myCurEdgeInd(1),
myCurEdgePar(Probing_Start)
{
{
myFace.Orientation(TopAbs_FORWARD);
}
//=======================================================================
//function : CheckPoint
//purpose :
//=======================================================================
Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint)
Standard_Boolean BRepClass_FaceExplorer::CheckPoint(gp_Pnt2d& thePoint)
{
Standard_Real anUMin = 0.0, anUMax = 0.0, aVMin = 0.0, aVMax = 0.0;
TopLoc_Location aLocation;
const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface(myFace, aLocation);
aSurface->Bounds(anUMin, anUMax, aVMin, aVMax);
if (Precision::IsInfinite(anUMin) || Precision::IsInfinite(anUMax) ||
Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
{
BRepTools::UVBounds(myFace, anUMin, anUMax, aVMin, aVMax);
if (Precision::IsInfinite(anUMin) || Precision::IsInfinite(anUMax) ||
Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
Precision::IsInfinite(aVMin) || Precision::IsInfinite(aVMax))
{
return Standard_True;
}
@@ -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;
@@ -137,7 +139,7 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
if (i != myCurEdgeInd)
continue;
const TopoDS_Shape &aLocalShape = anExpF.Current();
const TopoDS_Shape &aLocalShape = anExpF.Current();
const TopAbs_Orientation anOrientation = aLocalShape.Orientation();
if (anOrientation == TopAbs_FORWARD || anOrientation == TopAbs_REVERSED) {
@@ -146,27 +148,29 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
aC2d = BRep_Tool::CurveOnSurface(anEdge, myFace, aFPar, aLPar);
if (!aC2d.IsNull()) {
// Treatment of infinite cases.
if (Precision::IsNegativeInfinite(aFPar)) {
if (Precision::IsPositiveInfinite(aLPar)) {
aFPar = -1.;
aLPar = 1.;
} else {
aFPar = aLPar - 1.;
}
} else if (Precision::IsPositiveInfinite(aLPar))
aLPar = aFPar + 1.;
// Treatment of infinite cases.
if (Precision::IsNegativeInfinite(aFPar)) {
if (Precision::IsPositiveInfinite(aLPar)) {
aFPar = -1.;
aLPar = 1.;
}
else {
aFPar = aLPar - 1.;
}
}
else if (Precision::IsPositiveInfinite(aLPar))
aLPar = aFPar + 1.;
for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) {
aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
for (; myCurEdgePar < Probing_End; myCurEdgePar += Probing_Step) {
aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
gp_Vec2d aTanVec;
aC2d->D1(aParamIn, aPOnC, aTanVec);
Par = aPOnC.SquareDistance(P);
aC2d->D1(aParamIn, aPOnC, aTanVec);
Par = aPOnC.SquareDistance(P);
if (Par > aTolParConf2) {
gp_Vec2d aLinVec(P, aPOnC);
gp_Dir2d aLinDir(aLinVec);
if (Par > aTolParConf2) {
gp_Vec2d aLinVec(P, aPOnC);
gp_Dir2d aLinDir(aLinVec);
Standard_Real aTanMod = aTanVec.SquareMagnitude();
if (aTanMod < aTolParConf2)
@@ -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
@@ -185,28 +191,62 @@ Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P,
continue;
}
L = gp_Lin2d(P, aLinDir);
L = gp_Lin2d(P, aLinDir);
// Check if ends of a curve lie on a line.
aC2d->D0(aFPar, aPOnC);
// 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) {
Standard_Real aLDist = P.SquareDistance(aPOnC);
if (L.SquareDistance(aPOnC) > aTolParConf2) {
aC2d->D0(aLPar, aPOnC);
if (isSmallAngle)
{
//Try to find minimal distance between curve and line
if (L.SquareDistance(aPOnC) > aTolParConf2) {
myCurEdgePar += Probing_Step;
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;
}
if (myCurEdgePar >= Probing_End) {
myCurEdgeInd++;
myCurEdgePar = Probing_Start;
}
Par = Sqrt(Par);
return Standard_True;
}
}
}
}
Par = Sqrt(Par);
return Standard_True;
}
}
}
}
} // if (!aC2d.IsNull()) {
} // if (anOrientation == TopAbs_FORWARD ...
@@ -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;
}

View File

@@ -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);

View File

@@ -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 ||

View File

@@ -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;
}
}

View File

@@ -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>
@@ -172,14 +173,14 @@ private:
};
void CollectCoincidentVertices(const TopTools_ListOfShape& theL,
NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL);
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,
TopTools_ListOfShape& theNewEList);
const TopTools_DataMapOfShapeShape& theO2NV,
TopTools_ListOfShape& theNewEList);
void Add(const TopoDS_Edge& E, Standard_Boolean IsCheckGeometryProximity);

View File

@@ -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;
@@ -303,8 +301,8 @@ void BRepLib_MakeWire::CollectCoincidentVertices(const TopTools_ListOfShape& the
//function : CreateNewVertices
//purpose :
//=======================================================================
void BRepLib_MakeWire::CreateNewVertices(const NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL,
NCollection_DataMap<TopoDS_Vertex, TopoDS_Vertex>& theO2NV)
void BRepLib_MakeWire::CreateNewVertices(const NCollection_List<NCollection_List<TopoDS_Vertex>>& theGrVL,
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

View File

@@ -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 );
}
//=======================================================================

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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,41 +249,94 @@ 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)
{
// Update edges data
TopExp_Explorer aExplorer(myShape, TopAbs_EDGE);
for (; aExplorer.More(); aExplorer.Next())
{
const TopoDS_Edge& aEdge = TopoDS::Edge(aExplorer.Current());
if(!BRep_Tool::IsGeometric(aEdge))
continue;
Message_ProgressSentry anOuterSentry (theProgress, "Updating", 0, 100, 1);
update(aEdge);
// Update edges data
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))
continue;
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());
}
// Mesh faces
OSD_Parallel::ForEach(myFaces.begin(), myFaces.end(), *myMesh, !myParameters.InParallel);
if (!anOuterSentry.More())
{
myStatus = BRepMesh_UserBreak;
return;
}
commit();
anOuterSentry.Next(80);
{
// Mesh faces
FaceListFunctor aFacesFunctor (this, theProgress, myParameters.InParallel);
OSD_Parallel::For (0, myFaces.Size(), aFacesFunctor, !myParameters.InParallel);
}
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();

View File

@@ -25,6 +25,7 @@
#include <vector>
class Message_ProgressIndicator;
class Poly_Triangulation;
class TopoDS_Shape;
class TopoDS_Edge;
@@ -68,7 +69,10 @@ 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;

View File

@@ -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

View File

@@ -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"

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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,63 +354,150 @@ 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;
// 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);
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)
// Iterate on all solutions and collect the extreme solutions on all parallel segments.
for (Standard_Integer anIdx = 0; anIdx < aNbSol - 1; anIdx++)
{
isParallel = Standard_True;
for(Standard_Integer anIdx = aPnts.Lower(); anIdx <= aPnts.Upper() - 1; anIdx++)
const gp_XY& aCurrent = aPnts(anIdx);
const gp_XY& aNext = aPnts(anIdx + 1);
aVec(1) = (aCurrent.X() + aNext.X()) * 0.5;
aVec(2) = (aCurrent.Y() + aNext.Y()) * 0.5;
aFunc.Value(aVec, aVal);
if (Abs(aVal - aF) < Precision::Confusion())
{
const gp_XY& aCurrent = aPnts(anIdx);
const gp_XY& aNext = aPnts(anIdx + 1);
aVec(1) = (aCurrent.X() + aNext.X()) * 0.5;
aVec(2) = (aCurrent.Y() + aNext.Y()) * 0.5;
aFunc.Value(aVec, aVal);
if (Abs(aVal - aF) > Precision::Confusion())
// It seems the parallel segment is found.
// Save only extreme solutions on that segment.
if (bSaveSolution)
{
isParallel = Standard_False;
break;
// 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;
}
//=======================================================================

View File

@@ -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_TextFormatter.cxx
Font_UnicodeSubset.hxx

View File

@@ -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,
const Font_FontAspect theFontAspect,
const Standard_Real theSize)
bool Font_BRepFont::FindAndInit (const TCollection_AsciiString& theFontName,
const Font_FontAspect theFontAspect,
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
aWireDraft.Reverse();
//}
myBuilder.Add (aFaceDraft, aWireDraft);
if (!myFontParams.IsSingleStrokeFont)
{
// collect all wires and set CCW orientation
TopoDS_Face aFace;
myBuilder.MakeFace (aFace, mySurface, myPrecision);
myBuilder.Add (aFace, aWireDraft);
BRepTopAdaptor_FClass2d aClass2d (aFace, ::Precision::PConfusion());
TopAbs_State aState = aClass2d.PerformInfinitePoint();
if (aState != TopAbs_OUT)
{
// need to reverse
aWireDraft.Reverse();
}
aWires.Append (aWireDraft);
}
else
{
if (aFaceCompDraft.IsNull())
{
myBuilder.MakeCompound (aFaceCompDraft);
}
myBuilder.Add (aFaceCompDraft, aWireDraft);
}
}
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());
}
theShape = aComp;
buildFaces (aWires, theShape);
}
else if (!aFaceCompDraft.IsNull())
{
theShape = aFaceCompDraft;
}
myCache.Bind (theChar, theShape);

View File

@@ -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
@@ -53,12 +56,14 @@ public:
const Standard_Real theSize);
//! Constructor with initialization.
//! @param theFontName the font name
//! @param theFontAspect the font style
//! @param theSize the face size in model units
//! @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,
const Font_FontAspect theFontAspect,
const Standard_Real theSize);
Standard_EXPORT bool FindAndInit (const TCollection_AsciiString& theFontName,
const Font_FontAspect theFontAspect,
const Standard_Real theSize,
const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any);
//! Render single glyph as TopoDS_Shape.
//! @param theChar glyph identifier
@@ -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__

View File

@@ -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
@@ -29,12 +33,14 @@ IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient)
// purpose :
// =======================================================================
Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
: myFTLib (theFTLib),
myFTFace (NULL),
myPointSize (0U),
myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
myKernAdvance(new FT_Vector()),
myUChar (0U)
: myFTLib (theFTLib),
myFTFace (NULL),
myActiveFTFace(NULL),
myFontAspect (Font_FontAspect_Regular),
myWidthScaling(1.0),
myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
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 (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
if (!theData.IsNull())
{
//std::cerr << "Font '" << myFontPath << "' fail to load!\n";
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)
{
//Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' failed to load from file", Message_Trace);
Release();
return false;
}
}
if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font '") + myFontPath + "' doesn't contains Unicode charmap", Message_Trace);
Release();
return false;
}
else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 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;
}
else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
if (theParams.ToSynthesizeItalic)
{
//std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
Release();
return false;
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,
const Font_FontAspect theFontAspect,
const unsigned int thePointSize,
const unsigned int theResolution)
Handle(Font_FTFont) Font_FTFont::FindAndCreate (const TCollection_AsciiString& theFontName,
const Font_FontAspect theFontAspect,
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 (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
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;
}
myGlyphImg.SetTopDown (aBitmap.pitch > 0);
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
{
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);
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
{
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);
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);
}
// =======================================================================

View File

@@ -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.
//! @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
//! Initialize the font from the given file path.
//! @param theFontPath path to the font
//! @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.
//! @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
//! 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 NCollection_String& theFontName,
const Font_FontAspect theFontAspect,
const unsigned int thePointSize,
const unsigned int theResolution);
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 theParams initialization parameters
//! @param theStrictLevel search strict level for using aliases and fallback
//! @return true on success
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
FT_Face myFTFace; //!< FT face object
NCollection_String myFontPath; //!< font path
unsigned int myPointSize; //!< point size set by FT_Set_Char_Size
int32_t myLoadFlags; //!< default load flags
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
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
Image_PixMap myGlyphImg; //!< cached glyph plane
Standard_Utf32Char myUChar; //!< currently loaded unicode character
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__

View File

@@ -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

View File

@@ -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())
const Standard_Integer anOldIndex = myFontMap.FindIndex (theFont);
if (anOldIndex == 0)
{
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())
{
return Standard_True;
}
else if (theToOverride)
{
myListOfFonts.Remove (aFontIter);
}
else
{
return Standard_False;
}
}
myFontMap.Add (theFont);
return Standard_True;
}
myListOfFonts.Append (theFont);
Handle(Font_SystemFont) anOldFont = myFontMap.FindKey (anOldIndex);
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
{
if (anOldFont->FontPath ((Font_FontAspect )anAspectIter).IsEqual (theFont->FontPath ((Font_FontAspect )anAspectIter)))
{
continue;
}
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;
}
}
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,61 +474,86 @@ void Font_FontMgr::InitFontDataBase()
NCollection_Map<TCollection_AsciiString> aMapOfFontsDirs;
#if !defined(__ANDROID__) && !defined(__APPLE__)
const OSD_Protection aProtectRead (OSD_R, OSD_R, OSD_R, OSD_R);
// read fonts directories from font service config file (obsolete)
for (Standard_Integer anIter = 0; myFontServiceConf[anIter] != NULL; ++anIter)
if (FcConfig* aFcCfg = FcInitLoadConfig())
{
const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
OSD_File aFile (aFileOfFontsPath);
if (!aFile.Exists())
if (FcStrList* aFcFontDir = FcConfigGetFontDirs (aFcCfg))
{
continue;
}
aFile.Open (OSD_ReadOnly, aProtectRead);
if (!aFile.IsOpen())
{
continue;
}
Standard_Integer aNByte = 256;
Standard_Integer aNbyteRead;
TCollection_AsciiString aStr; // read string with information
while (!aFile.IsAtEnd())
{
Standard_Integer aLocation = -1;
Standard_Integer aPathLocation = -1;
aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
aLocation = aStr.Search ("catalogue=");
if (aLocation < 0)
for (;;)
{
aLocation = aStr.Search ("catalogue =");
}
aPathLocation = aStr.Search ("/");
if (aLocation > 0 && aPathLocation > 0)
{
aStr = aStr.Split (aPathLocation - 1);
TCollection_AsciiString aFontPath;
Standard_Integer aPathNumber = 1;
do
FcChar8* aFcFolder = FcStrListNext (aFcFontDir);
if (aFcFolder == NULL)
{
// Getting directory paths, which can be splitted by "," or ":"
aFontPath = aStr.Token (":,", aPathNumber);
aFontPath.RightAdjust();
if (!aFontPath.IsEmpty())
{
OSD_Path aPath(aFontPath);
addDirsRecursively (aPath, aMapOfFontsDirs);
}
aPathNumber++;
break;
}
while (!aFontPath.IsEmpty());
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)
{
const TCollection_AsciiString aFileOfFontsPath (myFontServiceConf[anIter]);
OSD_File aFile (aFileOfFontsPath);
if (!aFile.Exists())
{
continue;
}
aFile.Open (OSD_ReadOnly, aProtectRead);
if (!aFile.IsOpen())
{
continue;
}
Standard_Integer aNByte = 256;
Standard_Integer aNbyteRead;
TCollection_AsciiString aStr; // read string with information
while (!aFile.IsAtEnd())
{
Standard_Integer aLocation = -1;
Standard_Integer aPathLocation = -1;
aFile.ReadLine (aStr, aNByte, aNbyteRead); // reading 1 line (256 bytes)
aLocation = aStr.Search ("catalogue=");
if (aLocation < 0)
{
aLocation = aStr.Search ("catalogue =");
}
aPathLocation = aStr.Search ("/");
if (aLocation > 0 && aPathLocation > 0)
{
aStr = aStr.Split (aPathLocation - 1);
TCollection_AsciiString aFontPath;
Standard_Integer aPathNumber = 1;
do
{
// Getting directory paths, which can be splitted by "," or ":"
aFontPath = aStr.Token (":,", aPathNumber);
aFontPath.RightAdjust();
if (!aFontPath.IsEmpty())
{
OSD_Path aPath(aFontPath);
addDirsRecursively (aPath, aMapOfFontsDirs);
}
aPathNumber++;
}
while (!aFontPath.IsEmpty());
}
}
aFile.Close();
}
aFile.Close();
}
#endif
@@ -468,32 +573,32 @@ 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__)
OSD_Path aFolderPath (anIter.Value());
for (OSD_FileIterator aFileIter (aFolderPath, "*"); aFileIter.More(); aFileIter.Next())
{
OSD_Path aFontFilePath;
aFileIter.Values().Path (aFontFilePath);
TCollection_AsciiString aFontFileName;
aFontFilePath.SystemName (aFontFileName);
aFontFileName = anIter.Value() + "/" + aFontFileName;
Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString());
if (!aNewFont.IsNull())
{
myListOfFonts.Append (aNewFont);
}
}
#else
#if !defined(__ANDROID__) && !defined(__APPLE__)
OSD_File aReadFile (anIter.Value() + "/fonts.dir");
if (!aReadFile.Exists())
{
continue; // invalid fonts directory
#endif
OSD_Path aFolderPath (anIter.Value());
for (OSD_FileIterator aFileIter (aFolderPath, "*"); aFileIter.More(); aFileIter.Next())
{
OSD_Path aFontFilePath;
aFileIter.Values().Path (aFontFilePath);
TCollection_AsciiString aFontFileName;
aFontFilePath.SystemName (aFontFileName);
aFontFileName = anIter.Value() + "/" + aFontFileName;
if (Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontFileName.ToCString()))
{
RegisterFont (aNewFont, false);
}
}
#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 ("/");
}
Handle(TCollection_HAsciiString) aFontFileName =
new TCollection_HAsciiString (aLine.SubString (1, anEndOfFileName));
aFontPath->AssignCat (aFontFileName);
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(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (aXLFD, aFontPath);
Handle(Font_SystemFont) aNewFont = checkFont (aFtLibrary, aFontPath->ToCString());
if (aNewFontFromXLFD->IsValid() && !aNewFont.IsNull() &&
!aNewFont->IsEqual (aNewFontFromXLFD))
{
myListOfFonts.Append (aNewFont);
myListOfFonts.Append (aNewFontFromXLFD);
}
else if (!aNewFont.IsNull())
{
myListOfFonts.Append (aNewFont);
}
else if (aNewFontFromXLFD->IsValid())
{
myListOfFonts.Append (aNewFontFromXLFD);
Handle(Font_SystemFont) aNewFontFromXLFD = new Font_SystemFont (anXName);
aNewFontFromXLFD->SetFontPath (anXAspect, aFontPath);
if (!aNewFont->IsEqual (aNewFontFromXLFD))
{
RegisterFont (aNewFontFromXLFD, false);
}
}
}
}
}
@@ -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())
Handle(Font_SystemFont) aFont = myFontMap.Find (theFontName->String());
return (aFont.IsNull()
|| theFontAspect == Font_FontAspect_UNDEFINED
|| aFont->HasFontAspect (theFontAspect))
? aFont
: Handle(Font_SystemFont)();
}
// =======================================================================
// function : GetFont
// purpose :
// =======================================================================
Handle(Font_SystemFont) Font_FontMgr::GetFont (const TCollection_AsciiString& theFontName) const
{
return myFontMap.Find (theFontName);
}
// =======================================================================
// function : FindFallbackFont
// purpose :
// =======================================================================
Handle(Font_SystemFont) Font_FontMgr::FindFallbackFont (Font_UnicodeSubset theSubset,
Font_FontAspect theFontAspect) const
{
Font_FontAspect aFontAspect = theFontAspect;
switch (theSubset)
{
if (!theFontName->IsEmpty() && !aFontsIterator.Value()->FontName()->IsSameString (theFontName, Standard_False))
{
continue;
}
if (theFontAspect != Font_FA_Undefined && aFontsIterator.Value()->FontAspect() != theFontAspect)
{
continue;
}
if (theFontSize == -1 || aFontsIterator.Value()->FontHeight() == -1 ||
theFontSize == aFontsIterator.Value()->FontHeight())
{
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);
if (aFontAlias->IsSameString (aFontName, Standard_False))
Handle(Font_FontAliasSequence) anAliases;
if (aPass == 0)
{
aFontName = new TCollection_HAsciiString (Font_FontMgr_MapOfFontsAliases[anIter].FontName);
aFontAspect = Font_FontMgr_MapOfFontsAliases[anIter].FontAspect;
break;
myFontAliases.Find (aFontName, anAliases);
}
else if (theStrictLevel == Font_StrictLevel_Any)
{
anAliases = myFallbackAlias;
}
if (anAliases.IsNull()
|| anAliases->IsEmpty())
{
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;
}
}
}
if (aPass == 0)
{
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;
}
else if (!aFont.IsNull())
{
break;
}
}
}
// check font family alias with specified font aspect
if (theFontAspect != Font_FA_Undefined
&& theFontAspect != Font_FA_Regular
&& theFontAspect != aFontAspect)
if (aFont.IsNull()
&& theStrictLevel == Font_StrictLevel_Any)
{
aFont = GetFont (aFontName, theFontAspect, aFontSize);
if (!aFont.IsNull())
{
return aFont;
}
// try finding ANY font in case if even default fallback alias myFallbackAlias cannot be found
aFont = myFontMap.Find (TCollection_AsciiString());
}
if (aFont.IsNull())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString("Font_FontMgr, error: unable to find any font!", Message_Fail));
return Handle(Font_SystemFont)();
}
// check font alias with aspect in the name
aFont = GetFont (aFontName, aFontAspect, aFontSize);
if (!aFont.IsNull())
if ((theFontAspect != Font_FA_Undefined
&& !aFont->HasFontAspect (theFontAspect))
|| (!aFontName.IsEmpty()
&& !aFontName.IsEqual (aFont->FontKey())))
{
return aFont;
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");
}
// 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())
{
return aFont;
}
// 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())
{
return aFont;
}
return NULL; // Fonts are not found in the system.
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)();
}

View File

@@ -17,33 +17,67 @@
#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:
Standard_EXPORT static Handle(Font_FontMgr) GetInstance();
Standard_EXPORT const Font_NListOfSystemFont& GetAvailableFonts() const;
//! 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());
}
}
//! 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;
@@ -52,51 +86,119 @@ public:
//! If theFontAspect is Font_FA_Undefined returned font can have any FontAspect.
//! 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

View File

@@ -13,7 +13,14 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#define Font_NOF_ASCII_MONO "Courier"
#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"
#define Font_NOF_ASCII_DUPLEX "Times-Bold"

View File

@@ -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

View File

@@ -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())
{
MyVerification = Standard_False; // empty font description handler
}
if (theXLFD->IsEmpty())
{
MyVerification = Standard_False; // empty font description
}
return theOtherFont.get() == this
|| myFontKey.IsEqual (theOtherFont->myFontKey);
}
if (MyVerification)
{
MyFontName = theXLFD->Token ("-", 2);
TCollection_AsciiString aXLFD (theXLFD->ToCString());
// =======================================================================
// function : ToString
// purpose :
// =======================================================================
TCollection_AsciiString Font_SystemFont::ToString() const
{
TCollection_AsciiString aDesc;
aDesc += TCollection_AsciiString() + "'" + myFontName + "'";
// Getting font size for fixed size fonts
if (aXLFD.Search ("-0-0-0-0-") >= 0)
MyFaceSize = -1; // Scalable font
bool isFirstAspect = true;
aDesc += " [aspects: ";
for (int anAspectIter = 0; anAspectIter < Font_FontAspect_NB; ++anAspectIter)
{
if (!HasFontAspect ((Font_FontAspect )anAspectIter))
{
continue;
}
if (!isFirstAspect)
{
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)
{
if (!HasFontAspect ((Font_FontAspect )anAspectIter))
{
MyFontAspect = Font_FA_Bold;
continue;
}
else if (aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o"))
if (!isFirstAspect)
{
MyFontAspect = Font_FA_Italic;
aDesc += ";";
}
else
{
isFirstAspect = false;
}
aDesc += FontPath ((Font_FontAspect )anAspectIter);
}
}
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))
{
return Standard_False;
}
if (MyFontAspect != theOtherFont->FontAspect())
{
return Standard_False;
}
if (MyFaceSize != theOtherFont->FontHeight())
{
return Standard_False;
}
return Standard_True;
aDesc += "]";
return aDesc;
}

View File

@@ -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:
//! 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:
//! 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);
}
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

View 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

View File

@@ -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();

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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;
};

View File

@@ -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.

View File

@@ -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; }

View File

@@ -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
};

View File

@@ -42,7 +42,7 @@ class HLRAlgo_Coincidence
public:
DEFINE_STANDARD_ALLOC
Standard_EXPORT HLRAlgo_Coincidence() :
HLRAlgo_Coincidence() :
myFE(0),
myParam(0.),
myStBef(TopAbs_IN),

View File

@@ -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
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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
*/

View File

@@ -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;
}

View File

@@ -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
}

View File

@@ -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);

View File

@@ -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();
GeomAdaptor_Surface AS(S);
pid->Planar(AS.GetType() == GeomAbs_Plane);
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) {

View File

@@ -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

View File

@@ -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>

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
if (wline->NbPnts() < 2)
continue;
IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
if (wline->NbPnts() < 2)
continue;
}
//the method PutVertexOnLine can reduce the number of points in <wline>
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);
if (wline->NbPnts() < 2)
continue;
if(wline->NbVertex() == 0) {
IntPatch_Point vtx;

View File

@@ -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

View File

@@ -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,473 +604,378 @@ 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;
}
}
Standard_Integer nbTreated = 0;
for (Standard_Integer ip=0; ip < nbpt; ip++) {
GetLinePoint2d (L, W1[ip]+1, !OnFirst, U,V);
// 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();
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_Integer Irang = Standard_Integer(par) + 1;
if (Irang == Brise.NbPoints()) {
Irang--;
par = 1.;
}
else {
par =Abs(W2[ip]-par);
}
W = (1.-par)*Brise.Parameter(Irang) + par*Brise.Parameter(Irang+1);
}
Standard_Integer nbTreated = 0;
GetLinePoint2d (L, aW1+1, !OnFirst, U,V);
Standard_Boolean refined = Standard_False;
if (refine[ip])
Standard_Real par = IntegerPart(aW2);
Standard_Integer Irang = Standard_Integer(par) + 1;
if (Irang == Brise.NbPoints())
{
Irang--;
par = 1.;
}
else
{
par = Abs(aW2 - par);
}
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.
//--
//-- On injecte ce point ds les intersections Courbe-Surface
//--
IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
// MSV: extend UV bounds to not miss solution near the boundary
const Standard_Real margCoef = 0.004;
Standard_Boolean refined = Standard_False;
IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
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::SquareConfusion())
{
//------------------------------------------------------------------------
//-- On a trouve un point 2d approche Ua,Va intersection de la ligne
//-- de cheminement et de la restriction.
//--
//-- On injecte ce point ds les intersections Courbe-Surface
//--
IntPatch_CSFunction thefunc(OtherSurf,arc,Surf);
// MSV: extend UV bounds to not miss solution near the boundary
Standard_Real margCoef = 0.004;
IntPatch_CurvIntSurf IntCS(U,V,W,thefunc,edgeTol,margCoef);
if (IntCS.IsDone())
{
if (!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())
{
U2 = U;
V2 = V;
}
paramarc = IntCS.ParameterOnCurve();
refined = Standard_True;
}
}
U2 = U;
V2 = V;
}
else {
U2 = U; V2 = V;
paramarc = W;
arc->D0(paramarc,p2d);
Surf->D0(p2d.X(),p2d.Y(),ptsommet);
paramarc = IntCS.ParameterOnCurve();
refined = Standard_True;
}
if (refined) {
duplicate = Standard_False;
for (j=1; j<=locpt.Length();j++) {
if (ptsommet.Distance(locpt(j)) <= edgeTol) {
if (possiblyClosed) {
locpt2(j).Coord(U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
continue;
}
duplicate = Standard_True;
break;
}
}
if (!refine[ip] || refined) {
duplicate = Standard_False;
for (j=1; j<=locpt.Length();j++) {
if (ptsommet.Distance(locpt(j)) <= edgeTol) {
if (possiblyClosed) {
locpt2(j).Coord(U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
continue;
}
duplicate = Standard_True;
break;
if (!duplicate) {
Standard_Integer ParamApproxOnLine = Standard_Integer(aW1)+1;
arc->D1(paramarc,p2d,d2d);
U1 = p2d.X(); V1 = p2d.Y();
if (typL == IntPatch_Walking && SurfaceIsPeriodic) {
if (OnFirst)
Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U1,V1,U2,V2);
else
Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U2,V2,U1,V1);
}
locpt.Append(ptsommet);
locpt2.Append(gp_Pnt2d(U2,V2));
found = FindParameter(L,OtherSurf,edgeTol,ptsommet,gp_Pnt2d(U2,V2),
paramline,tgline,ParamApproxOnLine,OnFirst);
if (typL == IntPatch_Walking && found && possiblyClosed) {
// check in 2d
if (SurfaceIsUClosed || SurfaceIsVClosed) {
GetLinePoint2d (L, paramline, OnFirst, U,V);
if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
(SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
found = Standard_False;
}
if (found && (OSurfaceIsUClosed || OSurfaceIsVClosed)) {
GetLinePoint2d (L, paramline, !OnFirst, U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
found = Standard_False;
}
}
if (!found) {
continue;
}
if (!duplicate) {
Standard_Integer ParamApproxOnLine = Standard_Integer(W1[ip])+1;
VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,edgeTol,Domain,vtxarc);
Standard_Real vtxTol;
if (VtxOnArc) {
vtxTol = Tol3d(vtxarc,Domain);
if (edgeTol > vtxTol) vtxTol = edgeTol;
}
else vtxTol = edgeTol;
arc->D1(paramarc,p2d,d2d);
U1 = p2d.X(); V1 = p2d.Y();
if (typL == IntPatch_Walking && SurfaceIsPeriodic) {
if (OnFirst)
Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U1,V1,U2,V2);
else
Recadre(TypeS1,TypeS2,wlin,ParamApproxOnLine,U2,V2,U1,V1);
}
locpt.Append(ptsommet);
locpt2.Append(gp_Pnt2d(U2,V2));
found = FindParameter(L,OtherSurf,edgeTol,ptsommet,gp_Pnt2d(U2,V2),
paramline,tgline,ParamApproxOnLine,OnFirst);
if (typL == IntPatch_Walking && found && possiblyClosed) {
// check in 2d
if (SurfaceIsUClosed || SurfaceIsVClosed) {
GetLinePoint2d (L, paramline, OnFirst, U,V);
if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
(SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
found = Standard_False;
}
if (found && (OSurfaceIsUClosed || OSurfaceIsVClosed)) {
GetLinePoint2d (L, paramline, !OnFirst, U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
found = Standard_False;
}
}
if (!found) {
continue;
}
VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,edgeTol,Domain,vtxarc);
Standard_Real vtxTol;
if (VtxOnArc) {
vtxTol = Tol3d(vtxarc,Domain);
if (edgeTol > vtxTol) vtxTol = edgeTol;
}
else vtxTol = edgeTol;
//-- It is necessary to test that the point does not already exist
//-- - It can be already a point on arc
//-- BUT on a different arc
// MSV 27.03.2002: find the nearest point; add check in 2d
Standard_Integer ivtx = 0;
Standard_Real dmin = RealLast();
for (j=1; j<=Nbvtx; j++) {
const IntPatch_Point& Rptline = (typL == IntPatch_Walking
? wlin->Vertex(j)
: rlin->Vertex(j));
Standard_Boolean APointOnRstStillExist =
((OnFirst && Rptline.IsOnDomS1() && Rptline.ArcOnS1() == arc) ||
(!OnFirst && Rptline.IsOnDomS2() && Rptline.ArcOnS2() == arc));
if(!APointOnRstStillExist) {
if (possiblyClosed) {
if (SurfaceIsUClosed || SurfaceIsVClosed) {
if (OnFirst) Rptline.ParametersOnS1(U,V);
else Rptline.ParametersOnS2(U,V);
if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
(SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
continue;
}
if (OSurfaceIsUClosed || OSurfaceIsVClosed) {
if (OnFirst) Rptline.ParametersOnS2(U,V);
else Rptline.ParametersOnS1(U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
continue;
}
//-- It is necessary to test that the point does not already exist
//-- - It can be already a point on arc
//-- BUT on a different arc
// MSV 27.03.2002: find the nearest point; add check in 2d
Standard_Integer ivtx = 0;
Standard_Real dmin = RealLast();
for (j=1; j<=Nbvtx; j++) {
const IntPatch_Point& Rptline = (typL == IntPatch_Walking
? wlin->Vertex(j)
: rlin->Vertex(j));
Standard_Boolean APointOnRstStillExist =
((OnFirst && Rptline.IsOnDomS1() && Rptline.ArcOnS1() == arc) ||
(!OnFirst && Rptline.IsOnDomS2() && Rptline.ArcOnS2() == arc));
if(!APointOnRstStillExist) {
if (possiblyClosed) {
if (SurfaceIsUClosed || SurfaceIsVClosed) {
if (OnFirst) Rptline.ParametersOnS1(U,V);
else Rptline.ParametersOnS2(U,V);
if ((SurfaceIsUClosed && Abs(U-U1) > tolUClosed) ||
(SurfaceIsVClosed && Abs(V-V1) > tolVClosed))
continue;
}
Standard_Real dist = ptsommet.Distance(Rptline.Value());
Standard_Real dt = Max(vtxTol, Rptline.Tolerance());
if (dist < dmin) {
if (dist <= dt) {
ptline = Rptline;
ivtx = j;
if( surfacetype == GeomAbs_Cone ) {
ivtx = 0;
}
}
else {
// cancel previous solution because this point is better
// but its tolerance is not large enough
if (OSurfaceIsUClosed || OSurfaceIsVClosed) {
if (OnFirst) Rptline.ParametersOnS2(U,V);
else Rptline.ParametersOnS1(U,V);
if ((OSurfaceIsUClosed && Abs(U-U2) > tolOUClosed) ||
(OSurfaceIsVClosed && Abs(V-V2) > tolOVClosed))
continue;
}
}
Standard_Real dist = ptsommet.Distance(Rptline.Value());
Standard_Real dt = Max(vtxTol, Rptline.Tolerance());
if (dist < dmin) {
if (dist <= dt) {
ptline = Rptline;
ivtx = j;
if( surfacetype == GeomAbs_Cone ) {
ivtx = 0;
}
dmin = dist;
}
}
}
if (ivtx) {
if (ptline.Tolerance() > vtxTol) {
vtxTol = ptline.Tolerance();
if (!VtxOnArc) {
// now we should repeat attempt to coincide on a bound of arc
VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,vtxTol,Domain,vtxarc);
if (VtxOnArc) {
Standard_Real tol = Tol3d(vtxarc,Domain);
if (tol > vtxTol) vtxTol = tol;
}
}
}
}
if (typL == IntPatch_Walking)
VerifyTgline(wlin,(Standard_Integer)paramline,edgeTol,tgline);
Surf->D1(U1,V1,ptbid,d1u,d1v);
tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
normsurf = d1u.Crossed(d1v);
if (normsurf.Magnitude() < gp::Resolution()) {
transline.SetValue(Standard_True,IntSurf_Undecided);
transarc.SetValue(Standard_True,IntSurf_Undecided);
}
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
if (OnFirst)
Sommet.SetParameters(U1,V1,U2,V2);
else
Sommet.SetParameters(U2,V2,U1,V1);
if (VtxOnArc)
Sommet.SetVertex(OnFirst,vtxarc);
//---------------------------------------------------------
//-- lbr : On remplace le point d indice paramline sur la -
//-- ligne par le vertex . -
//---------------------------------------------------------
Sommet.SetParameter(paramline); // sur ligne d intersection
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
else {
// CAS DE FIGURE : en appelant s1 la surf sur laquelle on
// connait les pts sur restriction, et s2 celle sur laquelle
// on les cherche. Le point trouve verifie necessairement
// IsOnDomS1 = True.
// Pas vtxS1, pas vtxS2 :
// on recupere le point et on applique SetArcOnS2 et
// eventuellement SetVertexOnS2. Si on a deja IsOnDomS2,
// on considere que le point est deja traite, mais ne devrait
// pas se produire.
// vtxS1, pas vtxS2 :
// si pas IsOnDomS2 : pour chaque occurrence, faire SetArcOnS2,
// et eventuellement SetVertexOnS2.
// si IsOnDomS2 : impossible, on doit avoir IsVtxOnS2.
// vtxS1,vtxS2 :
// on doit avoir VtxOnArc = True. On duplique chaque occurrence
// "sur S1" du point en changeant ArcOnS2.
// pas vtxS1, vtxS2 :
// on doit avoir VtxOnArc = True. On duplique le point sur S1
// en changeant ArcOnS2.
Standard_Boolean OnDifferentRst =
((OnFirst && ptline.IsOnDomS1() && ptline.ArcOnS1() != arc) ||
(!OnFirst && ptline.IsOnDomS2() && ptline.ArcOnS2() != arc));
ptline.SetTolerance(vtxTol);
if ( (!ptline.IsVertexOnS1() && OnFirst)
|| (!ptline.IsVertexOnS2() && !OnFirst)
|| (OnDifferentRst)) {
if ( (!ptline.IsOnDomS2() && !OnFirst)
||(!ptline.IsOnDomS1() && OnFirst)
||(OnDifferentRst)) {
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
//ptline.SetParameter(paramline); //-- rajout lbr le 20 nov 97
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
if(OnDifferentRst) {
wlin->AddVertex(ptline);
Nbvtx++;
}
else {
wlin->Replace(ivtx,ptline);
}
}
else {
if(OnDifferentRst) {
rlin->AddVertex(ptline);
Nbvtx++;
}
else {
rlin->Replace(ivtx,ptline);
}
}
}
else if ( ( OnFirst && ptline.IsVertexOnS2())
||(!OnFirst && ptline.IsVertexOnS1())) {
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
Sommet.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
else {
//-- cout << "pb dans RstInt Type 1 " << endl;
// cancel previous solution because this point is better
// but its tolerance is not large enough
ivtx = 0;
}
dmin = dist;
}
}
}
if (ivtx) {
if (ptline.Tolerance() > vtxTol) {
vtxTol = ptline.Tolerance();
if (!VtxOnArc) {
// now we should repeat attempt to coincide on a bound of arc
VtxOnArc = CoincideOnArc(ptsommet,arc,Surf,vtxTol,Domain,vtxarc);
if (VtxOnArc) {
Standard_Real tol = Tol3d(vtxarc,Domain);
if (tol > vtxTol) vtxTol = tol;
}
}
else {
Handle(Adaptor3d_HVertex) vtxref = (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()) ;
if ( ( OnFirst && !ptline.IsOnDomS2())
||(!OnFirst && !ptline.IsOnDomS1())) {
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
}
}
if (typL == IntPatch_Walking)
VerifyTgline(wlin,(Standard_Integer)paramline,edgeTol,tgline);
Surf->D1(U1,V1,ptbid,d1u,d1v);
tgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
normsurf = d1u.Crossed(d1v);
if (normsurf.Magnitude() < gp::Resolution()) {
transline.SetValue(Standard_True,IntSurf_Undecided);
transarc.SetValue(Standard_True,IntSurf_Undecided);
}
else
IntSurf::MakeTransition(tgline,tgrst,normsurf,transline,transarc);
nbTreated++;
if (!ivtx) {
Sommet.SetValue(ptsommet,vtxTol,Standard_False); // pour tangence
if (OnFirst)
Sommet.SetParameters(U1,V1,U2,V2);
else
Sommet.SetParameters(U2,V2,U1,V1);
if (VtxOnArc)
Sommet.SetVertex(OnFirst,vtxarc);
//---------------------------------------------------------
//-- lbr : On remplace le point d indice paramline sur la -
//-- ligne par le vertex . -
//---------------------------------------------------------
Sommet.SetParameter(paramline); // sur ligne d intersection
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
else {
// CAS DE FIGURE : en appelant s1 la surf sur laquelle on
// connait les pts sur restriction, et s2 celle sur laquelle
// on les cherche. Le point trouve verifie necessairement
// IsOnDomS1 = True.
// Pas vtxS1, pas vtxS2 :
// on recupere le point et on applique SetArcOnS2 et
// eventuellement SetVertexOnS2. Si on a deja IsOnDomS2,
// on considere que le point est deja traite, mais ne devrait
// pas se produire.
// vtxS1, pas vtxS2 :
// si pas IsOnDomS2 : pour chaque occurrence, faire SetArcOnS2,
// et eventuellement SetVertexOnS2.
// si IsOnDomS2 : impossible, on doit avoir IsVtxOnS2.
// vtxS1,vtxS2 :
// on doit avoir VtxOnArc = True. On duplique chaque occurrence
// "sur S1" du point en changeant ArcOnS2.
// pas vtxS1, vtxS2 :
// on doit avoir VtxOnArc = True. On duplique le point sur S1
// en changeant ArcOnS2.
Standard_Boolean OnDifferentRst =
((OnFirst && ptline.IsOnDomS1() && ptline.ArcOnS1() != arc) ||
(!OnFirst && ptline.IsOnDomS2() && ptline.ArcOnS2() != arc));
ptline.SetTolerance(vtxTol);
if ( (!ptline.IsVertexOnS1() && OnFirst)
|| (!ptline.IsVertexOnS2() && !OnFirst)
|| (OnDifferentRst)) {
if ( (!ptline.IsOnDomS2() && !OnFirst)
||(!ptline.IsOnDomS1() && OnFirst)
||(OnDifferentRst)) {
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
//ptline.SetParameter(paramline); //-- rajout lbr le 20 nov 97
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
if(OnDifferentRst) {
wlin->AddVertex(ptline);
Nbvtx++;
}
else {
wlin->Replace(ivtx,ptline);
}
}
else {
if(OnDifferentRst) {
rlin->AddVertex(ptline);
Nbvtx++;
}
else {
rlin->Replace(ivtx,ptline);
}
for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
if (typL == IntPatch_Walking) {
ptline = wlin->Vertex(k);
}
else {
ptline = rlin->Vertex(k);
}
if ( ( OnFirst && ptline.IsVertexOnS1())
|| (!OnFirst && ptline.IsVertexOnS2())) {
if (Domain->Identical(vtxref, (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->Replace(k,ptline);
}
else {
rlin->Replace(k,ptline);
}
}
}
}
}
else if( ( OnFirst && ptline.IsVertexOnS2())
|| (!OnFirst && ptline.IsVertexOnS1())) {
// on doit avoir vtxons2 = vtxarc... pas de verif...
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
if (typL == IntPatch_Walking) {
ptline = wlin->Vertex(k);
}
else {
ptline = rlin->Vertex(k);
}
if ( ( OnFirst && ptline.IsVertexOnS1())
||(!OnFirst && ptline.IsVertexOnS2())) {
if (Domain->Identical(vtxref,(OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->Replace(k,ptline);
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->Replace(k,ptline);
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
}
}
}
else if ( ( OnFirst && ptline.IsVertexOnS2())
||(!OnFirst && ptline.IsVertexOnS1())) {
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
Sommet.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
//-- cout << "pb dans RstInt Type 2 " << endl;
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
else {
//-- cout << "pb dans RstInt Type 1 " << endl;
}
}
else {
Handle(Adaptor3d_HVertex) vtxref = (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()) ;
if ( ( OnFirst && !ptline.IsOnDomS2())
||(!OnFirst && !ptline.IsOnDomS1())) {
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->Replace(ivtx,ptline);
}
else {
rlin->Replace(ivtx,ptline);
}
for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
if (typL == IntPatch_Walking) {
ptline = wlin->Vertex(k);
}
else {
ptline = rlin->Vertex(k);
}
if ( ( OnFirst && ptline.IsVertexOnS1())
|| (!OnFirst && ptline.IsVertexOnS2())) {
if (Domain->Identical(vtxref, (OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
ptline.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (VtxOnArc)
ptline.SetVertex(OnFirst,vtxarc);
if (typL == IntPatch_Walking) {
wlin->Replace(k,ptline);
}
else {
rlin->Replace(k,ptline);
}
}
}
}
}
else if( ( OnFirst && ptline.IsVertexOnS2())
|| (!OnFirst && ptline.IsVertexOnS1())) {
// on doit avoir vtxons2 = vtxarc... pas de verif...
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->AddVertex(Sommet);
Nbvtx++;
}
for (k=1; k<=Nbvtx; k++) if (k != ivtx) {
if (typL == IntPatch_Walking) {
ptline = wlin->Vertex(k);
}
else {
ptline = rlin->Vertex(k);
}
if ( ( OnFirst && ptline.IsVertexOnS1())
||(!OnFirst && ptline.IsVertexOnS2())) {
if (Domain->Identical(vtxref,(OnFirst)? (ptline.VertexOnS1()) : (ptline.VertexOnS2()))) {
if (ptline.Tolerance() < vtxTol) ptline.SetTolerance(vtxTol);
Sommet = ptline;
Sommet.SetArc(OnFirst,arc,paramarc,transline,transarc);
if (typL == IntPatch_Walking) {
wlin->Replace(k,ptline);
wlin->AddVertex(Sommet);
Nbvtx++;
}
else {
rlin->Replace(k,ptline);
rlin->AddVertex(Sommet);
Nbvtx++;
}
}
}
}
}
else {
//-- cout << "pb dans RstInt Type 2 " << endl;
}
}
}
}

View File

@@ -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)
{
// Store this point.
aPurgedLineOn2S->Add(theWLine->Point(i));
anOldLineIdx++;
// 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);
}
// II: Delete out of borders points.
aLocalWLine = DeleteOuterPoints(aLocalWLine, theS1, theS2, theDom1, theDom2);
// III: Delete points by tube criteria.
Handle(IntPatch_WLine) aLocalWLineTube =

View File

@@ -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:

View File

@@ -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);

View File

@@ -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;

View File

@@ -2361,7 +2361,16 @@ 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,7 +2411,16 @@ 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--)

View File

@@ -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) {
@@ -1511,7 +1511,7 @@ Standard_Boolean ChoixUV(const TopoDS_Edge& Last,
BRepAdaptor_Surface surf(F,Standard_False); // no restriction
surf.D0 (plst.X(), plst.Y(), aPlst);
gp_Dir2d ref2d(dlst);
Handle(Geom2d_Curve) C2d;
@@ -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);

View File

@@ -532,6 +532,9 @@ Standard_Boolean Project(const TopoDS_Vertex& V,
Standard_Boolean valret = Standard_False;
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
Standard_Real aUmin, aUmax, aVmin, aVmax;
ShapeAnalysis::GetFaceUVBounds(F, aUmin, aUmax, aVmin, aVmax);
if (theEdge.IsNull())
{
@@ -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()) )

View File

@@ -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;
}
}
}

View File

@@ -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>
{

View File

@@ -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

View File

@@ -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.

View File

@@ -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()
{

View File

@@ -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;
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;
}

View File

@@ -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