mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
280a080587 | ||
|
c3d250cc97 | ||
|
07045ddcf5 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -35,8 +35,6 @@ Release
|
||||
*.suo
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.VC.db
|
||||
*.VC.opendb
|
||||
*.ipch
|
||||
*.aps
|
||||
|
||||
|
@@ -211,11 +211,9 @@ foreach (USED_ITEM ${USED_EXTERNLIB_AND_TOOLKITS})
|
||||
string (REGEX MATCH "^TK" TK_FOUND ${USED_ITEM})
|
||||
string (REGEX MATCH "^vtk" VTK_FOUND ${USED_ITEM})
|
||||
|
||||
if (NOT "${TK_FOUND}" STREQUAL "")
|
||||
if (NOT "${TK_FOUND}" STREQUAL "" OR NOT "${VTK_FOUND}" STREQUAL "")
|
||||
list (APPEND USED_TOOLKITS_BY_CURRENT_PROJECT ${USED_ITEM})
|
||||
elseif (NOT "${VTK_FOUND}" STREQUAL "")
|
||||
list (APPEND USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT ${USED_ITEM})
|
||||
if (BUILD_SHARED_LIBS AND INSTALL_VTK AND COMMAND OCCT_INSTALL_VTK)
|
||||
if (NOT "${VTK_FOUND}" STREQUAL "" AND BUILD_SHARED_LIBS AND INSTALL_VTK AND COMMAND OCCT_INSTALL_VTK)
|
||||
OCCT_INSTALL_VTK(${USED_ITEM})
|
||||
endif()
|
||||
else()
|
||||
@@ -278,29 +276,18 @@ endif()
|
||||
if("${VTK_RENDERING_BACKEND}" STREQUAL "OpenGL2")
|
||||
add_definitions(-DVTK_OPENGL2_BACKEND)
|
||||
foreach (VTK_EXCLUDE_LIBRARY vtkRenderingOpenGL vtkRenderingFreeTypeOpenGL)
|
||||
list (FIND USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT "${VTK_EXCLUDE_LIBRARY}" IS_VTK_OPENGL_FOUND)
|
||||
list (FIND USED_TOOLKITS_BY_CURRENT_PROJECT "${VTK_EXCLUDE_LIBRARY}" IS_VTK_OPENGL_FOUND)
|
||||
if (NOT ${IS_VTK_OPENGL_FOUND} EQUAL -1)
|
||||
list (REMOVE_ITEM USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT ${VTK_EXCLUDE_LIBRARY})
|
||||
list (REMOVE_ITEM USED_TOOLKITS_BY_CURRENT_PROJECT ${VTK_EXCLUDE_LIBRARY})
|
||||
if (${VTK_EXCLUDE_LIBRARY} STREQUAL vtkRenderingOpenGL)
|
||||
list (APPEND USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT vtkRenderingOpenGL2)
|
||||
if(VTK_MAJOR_VERSION GREATER 6)
|
||||
list (APPEND USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT vtkRenderingGL2PSOpenGL2)
|
||||
endif()
|
||||
list (APPEND USED_TOOLKITS_BY_CURRENT_PROJECT vtkRenderingOpenGL2)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
if(VTK_MAJOR_VERSION EQUAL 6 AND VTK_MINOR_VERSION GREATER 2 OR VTK_MAJOR_VERSION GREATER 6)
|
||||
list (FIND USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT "vtkRenderingFreeTypeOpenGL" IS_VTK_RENDER_FREETYPE_FOUND)
|
||||
if (NOT ${IS_VTK_RENDER_FREETYPE_FOUND} EQUAL -1)
|
||||
list (REMOVE_ITEM USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT "vtkRenderingFreeTypeOpenGL")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
target_link_libraries (${PROJECT_NAME} PUBLIC ${USED_TOOLKITS_BY_CURRENT_PROJECT})
|
||||
target_link_libraries (${PROJECT_NAME} PRIVATE ${USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT})
|
||||
target_link_libraries (${PROJECT_NAME} ${USED_TOOLKITS_BY_CURRENT_PROJECT} ${USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT})
|
||||
endif()
|
||||
|
||||
# suppress deprecation warnings inside OCCT itself for old gcc versions with unavailable Standard_DISABLE_DEPRECATION_WARNINGS
|
||||
|
@@ -2718,38 +2718,6 @@ To enable the safe processing mode for the operation in DRAW, it is necessary to
|
||||
bnondestructive 1
|
||||
~~~~
|
||||
|
||||
@subsection occt_algorithms_11a_4 Disabling check of the input solids for inverted status
|
||||
|
||||
By default, all input solids are checked for inverted status, i.e. the solids are classified to understand if they are holes in the space (negative volumes) or normal solids (positive volumes). The possibility to disable the check of the input solids for inverted status is the advanced option in Boolean Operation component. This option can be applied to all Basic operations such as General Fuse, Splitting, Boolean, Section, Maker Volume, Cells building.
|
||||
This option allows avoiding time-consuming classification of the input solids and operate with them as with positive volumes, saving up to 10 percent of time on the cases with big number of input solids.
|
||||
|
||||
The classification should be disabled only if the user is sure that there are no negative volumes among the input solids, otherwise the result may be invalid.
|
||||
|
||||
@subsubsection occt_algorithms_11a_4_1 Usage
|
||||
|
||||
#### API level
|
||||
|
||||
To enable/disable the classification of the input solids it is necessary to call *SetCheckInverted()* method with the appropriate value:
|
||||
~~~~
|
||||
BOPAlgo_Builder aGF;
|
||||
//
|
||||
....
|
||||
// disabling the classification of the input solid
|
||||
aGF.SetCheckInverted(Standard_False);
|
||||
//
|
||||
....
|
||||
~~~~
|
||||
|
||||
#### TCL level
|
||||
To enable/disable the classification of the solids in DRAW, it is necessary to call the *bcheckinverted* command with appropriate value:
|
||||
* 0 - disabling the classification;
|
||||
* 1 - default value, enabling the classification.
|
||||
|
||||
~~~~
|
||||
bcheckinverted 0
|
||||
~~~~
|
||||
|
||||
|
||||
@section occt_algorithms_ers Errors and warnings reporting system
|
||||
|
||||
The chapter describes the Error/Warning reporting system of the algorithms in the Boolean Component.
|
||||
|
@@ -91,18 +91,18 @@ XDE can read and write colors and layers assigned to shapes or their subparts (d
|
||||
|
||||
@figure{/user_guides/xde/images/xde_image006.png,"Colors and Layers",240}
|
||||
|
||||
@subsection occt_xde_1_7 Geometric Dimensions & Tolerances (GD\&T)
|
||||
@subsection occt_xde_1_7 Geometric Dimensions & Tolerances (GD&T)
|
||||
|
||||
GD\&T are a type of Product and Manufacturing Information (PMI) that can be either computed automatically by a CAD system,
|
||||
GD&T are a type of Product and Manufacturing Information (PMI) that can be either computed automatically by a CAD system,
|
||||
or entered manually by the user. For detailed information use <a href="https://www.cax-if.org/documents/rec_pracs_pmi_v40.pdf">CAx-IF Recommended Practices
|
||||
for the Representation and Presentation of Product Manufacturing Information (PMI) (AP242)</a>
|
||||
|
||||
XDE can read and write GD\&T data of the following types:
|
||||
XDE can read and write GD&T data of the following types:
|
||||
* dimensions, such as distance, length, radius and so on;
|
||||
* geometric tolerances;
|
||||
* datums, i.e a theoretically exact geometric references, such as point, line or plane, to which toleranced features are related.
|
||||
|
||||
XDE supports two presentations of GD\&T data:
|
||||
XDE supports two presentations of GD&T data:
|
||||
* semantic presentation, i.e. data is stored in a machine-consumable way and includes all information required to understand the
|
||||
specification without the aid of any presentation elements;
|
||||
* tessellated presentation, i.e. data is displayed in a human-readable way.
|
||||
@@ -660,42 +660,42 @@ To remove a Color and all the references to it (so that the related shapes will
|
||||
myColors->RemoveColor(ColLabel);
|
||||
~~~~~
|
||||
|
||||
@subsection occt_xde_2_7 Geometric Dimensions & Tolerances (GD\&T)
|
||||
@subsection occt_xde_2_7 Geometric Dimensions & Tolerances (GD&T)
|
||||
|
||||
XDE can read and write GD\&T assigned to shapes or their subparts (down to the level of faces and edges) to and from STEP formats.
|
||||
XDE can read and write GD&T assigned to shapes or their subparts (down to the level of faces and edges) to and from STEP formats.
|
||||
|
||||
In an XDE document, GD\&T are managed by the class *XCAFDoc_DimTolTool*. It works basing on the same principles as ShapeTool works with Shapes. This tool can be provided on the Main Label or on any sub-label. The GD\&T entities themselves are defined as the following sub-classes of *TDF_Attribute*:
|
||||
In an XDE document, GD&T are managed by the class *XCAFDoc_DimTolTool*. It works basing on the same principles as ShapeTool works with Shapes. This tool can be provided on the Main Label or on any sub-label. The GD&T entities themselves are defined as the following sub-classes of *TDF_Attribute*:
|
||||
* *XCAFDoc_Dimension* - for dimensions;
|
||||
* *XCAFDoc_GeomTolerance* - for geometric tolerances;
|
||||
* *XCAFDoc_Datum* - for geometric tolerance Datums.
|
||||
A GD\&T type is identified by the attributes listed above, i.e. *XCAFDoc_DimTolTool* methods working with particular entity types check
|
||||
A GD&T type is identified by the attributes listed above, i.e. *XCAFDoc_DimTolTool* methods working with particular entity types check
|
||||
for presence of the corresponding attributes in passed labels. One can use methods of *XCAFDoc_DimTolTool* beginning with 'Is' for this purpose.
|
||||
|
||||
GD\&T entities are stored in a child of the starting document label 0.1.4.
|
||||
Each GD\&T entity then corresponds to the dedicated label, the property itself is one of access classes:
|
||||
GD&T entities are stored in a child of the starting document label 0.1.4.
|
||||
Each GD&T entity then corresponds to the dedicated label, the property itself is one of access classes:
|
||||
* *XCAFDimTolObject_DimensionObject* - for dimensions;
|
||||
* *XCAFDimTolObject_GeomToleranceObject* - for geometric tolerances;
|
||||
* *XCAFDimTolObject_DatumObject* - for geometric tolerance Datums.
|
||||
|
||||
GD\&Ts and Shapes are related to by Graph Nodes.
|
||||
GD&Ts and Shapes are related to by Graph Nodes.
|
||||
|
||||
These definitions are common to various exchange formats, at least for STEP.
|
||||
|
||||
@subsubsection occt_xde_2_7_1 Initialization
|
||||
To query, edit, or initialize a Document to handle GD\&Ts of XCAF, use:
|
||||
To query, edit, or initialize a Document to handle GD&Ts of XCAF, use:
|
||||
~~~~~
|
||||
Handle(XCAFDoc_DimTolTool) myDimTolTool =
|
||||
XCAFDoc_DocumentTool::DimTolTool(Doc->Main());
|
||||
~~~~~
|
||||
This call can be used at any time. When it is used for the first time, a relevant structure is added to the document. This definition is used for all later GD\&T calls and is not repeated for them.
|
||||
This call can be used at any time. When it is used for the first time, a relevant structure is added to the document. This definition is used for all later GD&T calls and is not repeated for them.
|
||||
|
||||
@subsubsection occt_xde_2_7_2 Adding a GD\&T
|
||||
*XCAFDoc_DimTolTool* provides methods to create GD\&T 'empty' entities:
|
||||
@subsubsection occt_xde_2_7_2 Adding a GD&T
|
||||
*XCAFDoc_DimTolTool* provides methods to create GD&T 'empty' entities:
|
||||
* *AddDimension* - for a new dimension;
|
||||
* *AddGeomTolerance* - for a new geometric tolerance;
|
||||
* *AddDatum* - for a new geometric tolerance datum.
|
||||
|
||||
All methods create a sub-label for the corresponding GD\&T entity of the tool master label and attach an attribute specific for the
|
||||
All methods create a sub-label for the corresponding GD&T entity of the tool master label and attach an attribute specific for the
|
||||
created entity.
|
||||
|
||||
Here is an example of adding a new dimension:
|
||||
@@ -706,10 +706,10 @@ if (!aDimLabel.IsNull())
|
||||
// error processing
|
||||
}
|
||||
~~~~~
|
||||
A similar approach can be used for other GD\&T types.
|
||||
A similar approach can be used for other GD&T types.
|
||||
|
||||
@subsubsection occt_xde_2_7_3 Editing a GD\&T
|
||||
A newly added GD\&T entity is empty. To set its data a corresponding access object should be used as it is demonstrated
|
||||
@subsubsection occt_xde_2_7_3 Editing a GD&T
|
||||
A newly added GD&T entity is empty. To set its data a corresponding access object should be used as it is demonstrated
|
||||
below, where the dimension becomes the linear distance between two points.
|
||||
~~~~~
|
||||
Handle(XCAFDoc_Dimension) aDimAttr;
|
||||
@@ -726,10 +726,10 @@ if (!aDimAttr.IsNull())
|
||||
aDimAttr->SetObject(aDimObject);
|
||||
}
|
||||
~~~~~
|
||||
A similar approach can be used for other GD\&T types.
|
||||
A similar approach can be used for other GD&T types.
|
||||
|
||||
@subsubsection occt_xde_2_7_4 Linking GD\&Ts
|
||||
To link a GD\&T entity with other OCAF labels (e.g. representing shapes) one should use the following methods:
|
||||
@subsubsection occt_xde_2_7_4 Linking GD&Ts
|
||||
To link a GD&T entity with other OCAF labels (e.g. representing shapes) one should use the following methods:
|
||||
* *SetDimension* - for dimensions;
|
||||
* *SetGeomTolerance* - for geometric tolerances;
|
||||
* SetDatum - for geometric tolerance datums.
|
||||
@@ -748,20 +748,20 @@ aDGTTool->SetDimension(aShapes1, aShapes2, aDimLabel);
|
||||
|
||||
In addition, a special method *SetDatumToGeomTol* should be used to link a datum with a geometric tolerance.
|
||||
|
||||
@subsubsection occt_xde_2_7_5 Finding GD\&Ts and reference shapes
|
||||
@subsubsection occt_xde_2_7_5 Finding GD&Ts and reference shapes
|
||||
|
||||
*XCAFDimTolObjects_Tool* class provides basic capabilities for searching GD\&Ts linked to shapes.
|
||||
*XCAFDimTolObjects_Tool* class provides basic capabilities for searching GD&Ts linked to shapes.
|
||||
Using the tool one can get sequences of dimensions, geometric tolerances and datums linked with a shape. A series of related datums is also returned for geometric tolerances.
|
||||
|
||||
To get reference shapes for a GD\&T entity one can use *GetRefShapeLabel* from *XCAFDoc_DimTolTool*.
|
||||
To get reference shapes for a GD&T entity one can use *GetRefShapeLabel* from *XCAFDoc_DimTolTool*.
|
||||
|
||||
*XCAFDoc_DimTolTool* provides methods to get lists of all dimensions, geometric tolerances and datums.
|
||||
|
||||
@subsubsection occt_xde_2_7_6 Storing custom data
|
||||
Every GD\&T entity in XDE is represented as a label with attached attribute identifying entity type. All specific data is
|
||||
Every GD&T entity in XDE is represented as a label with attached attribute identifying entity type. All specific data is
|
||||
stored in sub-labels in standard OCAF attributes, such as *TDataStd_Integer*, *TDataStd_IntegerArray*, *TDataStd_RealArray* and so on.
|
||||
Sub-label tags are reserved for internal use and cannot be used for storing custom data. The following tag ranges are reserved for
|
||||
GD\&T entities:
|
||||
GD&T entities:
|
||||
* 1 - 17 - for dimensions;
|
||||
* 1 - 17 - for geometric tolerances;
|
||||
* 1 - 19 - for datums.
|
||||
@@ -834,7 +834,7 @@ for (TDF_LabelSequence::Iterator anIt(aClipPlaneLbls); anIt.More(); anIt.Next())
|
||||
|
||||
@subsection occt_xde_2_9 Saved views
|
||||
|
||||
In an XDE document, Views are managed by the class *XCAFDoc_ViewTool*. It works basing on the same principles as ShapeTool works with Shapes. This tool can be provided on the Main Label or on any sub-label. Views are stored in a child of the starting document label 0.1.7, where a view itself is defined as *XCAFDoc_View* sub-class of *TDF_Attribute*. Views and selected shapes, clipping planes, GD\&Ts and notes are related to by Graph Nodes.
|
||||
In an XDE document, Views are managed by the class *XCAFDoc_ViewTool*. It works basing on the same principles as ShapeTool works with Shapes. This tool can be provided on the Main Label or on any sub-label. Views are stored in a child of the starting document label 0.1.7, where a view itself is defined as *XCAFDoc_View* sub-class of *TDF_Attribute*. Views and selected shapes, clipping planes, GD&Ts and notes are related to by Graph Nodes.
|
||||
|
||||
To query, edit, or initialize a Document to handle views of XCAF, use:
|
||||
~~~~~
|
||||
@@ -864,7 +864,7 @@ if (!aViewAttr.IsNull())
|
||||
}
|
||||
~~~~~
|
||||
|
||||
To set shapes, clipping planes, GD\&Ts and notes selected for the view use one of overloaded *SetView* methods of *XCAFDoc_ViewTool*.
|
||||
To set shapes, clipping planes, GD&Ts and notes selected for the view use one of overloaded *SetView* methods of *XCAFDoc_ViewTool*.
|
||||
To set only clipping planes one should use *SetClippingPlanes* method.
|
||||
~~~~~
|
||||
TDF_LabelSequence aShapes; ...
|
||||
@@ -891,26 +891,23 @@ for (TDF_LabelSequence::Iterator anIt(aViewLbls); anIt.More(); anIt.Next())
|
||||
}
|
||||
~~~~~
|
||||
|
||||
To get shapes, clipping planes, GD\&Ts or notes associated with a particular view use the following methods:
|
||||
To get shapes, clipping planes, GD&Ts or notes associated with a particular view use the following methods:
|
||||
* *GetRefShapeLabel* - returns a sequence of associated shape labels;
|
||||
* *GetRefGDTLabel* - returns a sequence of associated GDT labels;
|
||||
* *GetRefClippingPlaneLabel* - returns a sequence of associated clipping plane labels;
|
||||
* *GetRefNoteLabel* - returns a sequence of associated note labels;
|
||||
* *GetRefAnnotationLabel* - returns a sequence of associated annotated labels.
|
||||
|
||||
And vice versa, to get views that display a particular clipping plane, GD\&T or note use the following methods:
|
||||
And vice versa, to get views that display a particular clipping plane, GD&T or note use the following methods:
|
||||
* *GetViewLabelsForShape* - returns a sequence of associated view labels for a shape;
|
||||
* *GetViewLabelsForGDT* - returns a sequence of associated view labels for a GD\&T;
|
||||
* *GetViewLabelsForGDT* - returns a sequence of associated view labels for a GD&T;
|
||||
* *GetViewLabelsForClippingPlane* - returns a sequence of associated view labels for a clipping plane;
|
||||
* *GetViewLabelsForNote* - returns a sequence of associated view labels for a note;
|
||||
* *GetViewLabelsForAnnotation* - returns a sequence of associated view labels for an annotated label.
|
||||
|
||||
@subsection occt_xde_2_10 Custom notes
|
||||
|
||||
In an XDE document, custom notes are managed by the class *XCAFDoc_NotesTool*.
|
||||
It works basing on the same principles as ShapeTool works with Shapes.
|
||||
This tool can be provided on the Main Label or on any sub-label.
|
||||
The Property itself is defined as sub-class of *XCAFDoc_Note* abstract class, which is a sub-class of *TDF_Attribute* one.
|
||||
In an XDE document, custom notes are managed by the class *XCAFDoc_NotesTool*. It works basing on the same principles as ShapeTool works with Shapes. This tool can be provided on the Main Label or on any sub-label. The Property itself is defined as sub-class of *XCAFDoc_Note* abstract class, which is a sub-class of *TDF_Attribute* one.
|
||||
|
||||
Custom notes are stored in a child of the *XCAFDoc_NotesTool* label, at label 0.1.9.1. Each note then corresponds to a dedicated label. A note may be attached to a document item identified by a label, a sub-shape identified by integer index or an attribute identified by GUID. Annotations are stored in a child of the *XCAFDoc_NotesTool* label, at label 0.1.9.2.
|
||||
Notes binding is done through *XCAFDoc_GraphNode* attribute.
|
||||
@@ -1045,7 +1042,7 @@ The same can be said for Viewing: presentations can be defined from Shapes and C
|
||||
|
||||
There are several important points to consider:
|
||||
* Previously defined Readers and Writers for dealing with Shapes only, whether Standard or Advanced, remain unchanged in their form and in their dependencies. In addition, functions other than mapping are also unchanged.
|
||||
* XDE provides mapping with data other than Shapes. Names, Colors, Layers, GD\&T, Clipping planes, Views, Validation Properties (Centroid, Volume, Area), and Assembly Structure are hierarchic with rigid motion. Currently, Clipping planes and Views writing supported for XBF format only.
|
||||
* XDE provides mapping with data other than Shapes. Names, Colors, Layers, GD&T, Clipping planes, Views, Validation Properties (Centroid, Volume, Area), and Assembly Structure are hierarchic with rigid motion. Currently, Clipping planes and Views writing supported for XBF format only.
|
||||
* XDE mapping is relevant for use within the Advanced level of Data Exchanges, rather than Standard ones, because a higher level of information is better suited to a higher quality of shapes. In addition, this allows to avoid the multiplicity of combinations between various options. Note that this choice is not one of architecture but of practical usage and packaging.
|
||||
* Reader and Writer classes for XDE are generally used like those for Shapes. However, their use is adapted to manage a Document rather than a Shape.
|
||||
|
||||
|
@@ -457,10 +457,6 @@ void AIS_InteractiveContext::Display (const Handle(AIS_InteractiveObject)& theIO
|
||||
{
|
||||
Erase (theIObj, theToUpdateViewer);
|
||||
Load (theIObj, theSelectionMode, theToAllowDecomposition);
|
||||
if (Handle(AIS_GlobalStatus)* aStatusPtr = myObjects.ChangeSeek (theIObj))
|
||||
{
|
||||
(*aStatusPtr)->SetDisplayMode (theDispMode);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -488,7 +484,7 @@ void AIS_InteractiveContext::Display (const Handle(AIS_InteractiveObject)& theIO
|
||||
{
|
||||
Handle(AIS_GlobalStatus) aStatus = new AIS_GlobalStatus (AIS_DS_Displayed, theDispMode, theSelectionMode);
|
||||
myObjects.Bind (theIObj, aStatus);
|
||||
myMainVwr->StructureManager()->RegisterObject (theIObj);
|
||||
Handle(Graphic3d_ViewAffinity) anAffinity = myMainVwr->StructureManager()->RegisterObject (theIObj);
|
||||
myMainPM->Display(theIObj, theDispMode);
|
||||
if (theSelectionMode != -1)
|
||||
{
|
||||
@@ -571,13 +567,15 @@ void AIS_InteractiveContext::Load (const Handle(AIS_InteractiveObject)& theIObj,
|
||||
return;
|
||||
}
|
||||
|
||||
if (theSelMode == -1
|
||||
&& !theToAllowDecomposition)
|
||||
{
|
||||
if (!myObjects.IsBound (theIObj))
|
||||
{
|
||||
Standard_Integer aDispMode, aHiMod, aSelModeDef;
|
||||
GetDefModes (theIObj, aDispMode, aHiMod, aSelModeDef);
|
||||
Handle(AIS_GlobalStatus) aStatus = new AIS_GlobalStatus (AIS_DS_Erased, aDispMode, theSelMode != -1 ? theSelMode : aSelModeDef);
|
||||
Handle(AIS_GlobalStatus) aStatus = new AIS_GlobalStatus (AIS_DS_Erased, aDispMode, aSelModeDef);
|
||||
myObjects.Bind (theIObj, aStatus);
|
||||
myMainVwr->StructureManager()->RegisterObject (theIObj);
|
||||
}
|
||||
|
||||
// Register theIObj in the selection manager to prepare further activation of selection
|
||||
@@ -587,6 +585,7 @@ void AIS_InteractiveContext::Load (const Handle(AIS_InteractiveObject)& theIObj,
|
||||
mgrSelector->Load (theIObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Erase
|
||||
@@ -786,7 +785,6 @@ Standard_Boolean AIS_InteractiveContext::KeepTemporary(const Handle(AIS_Interact
|
||||
Standard_False);
|
||||
// GS->SubIntensityOn();
|
||||
myObjects.Bind(anIObj,GS);
|
||||
myMainVwr->StructureManager()->RegisterObject (anIObj);
|
||||
mgrSelector->Load(anIObj);
|
||||
mgrSelector->Activate(anIObj,SM,myMainSel);
|
||||
|
||||
|
@@ -121,6 +121,7 @@ public: //! @name object display management
|
||||
//! If AllowDecomp = Standard_True and, if the interactive object is of the "Shape" type,
|
||||
//! these "standard" selection modes will be automatically activated as a function of the modes present in the Local Context.
|
||||
//! The loaded objects will be selectable but displayable in highlighting only when detected by the Selector.
|
||||
//! This method is available only when Local Contexts are open.
|
||||
Standard_EXPORT void Load (const Handle(AIS_InteractiveObject)& aniobj, const Standard_Integer SelectionMode = -1, const Standard_Boolean AllowDecomp = Standard_False);
|
||||
|
||||
//! Hides the object. The object's presentations are simply flagged as invisible and therefore excluded from redrawing.
|
||||
|
@@ -25,7 +25,6 @@
|
||||
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_DataMapOfShapeShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeShape.hxx>
|
||||
#include <BOPCol_ListOfShape.hxx>
|
||||
#include <BOPCol_MapOfShape.hxx>
|
||||
#include <BOPCol_MapOfOrientedShape.hxx>
|
||||
@@ -51,7 +50,6 @@
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopLoc_Location.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
@@ -71,7 +69,65 @@ static
|
||||
static
|
||||
void MakeInternalWires(const BOPCol_IndexedMapOfShape& ,
|
||||
BOPCol_ListOfShape& );
|
||||
static
|
||||
void GetWire(const TopoDS_Shape& ,
|
||||
TopoDS_Shape& );
|
||||
//
|
||||
|
||||
//
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_ShapeBox2D
|
||||
//purpose : Auxiliary class
|
||||
//=======================================================================
|
||||
class BOPAlgo_ShapeBox2D {
|
||||
public:
|
||||
BOPAlgo_ShapeBox2D() {
|
||||
myIsHole=Standard_False;
|
||||
};
|
||||
//
|
||||
~BOPAlgo_ShapeBox2D() {
|
||||
};
|
||||
//
|
||||
void SetShape(const TopoDS_Shape& aS) {
|
||||
myShape=aS;
|
||||
};
|
||||
//
|
||||
const TopoDS_Shape& Shape()const {
|
||||
return myShape;
|
||||
};
|
||||
//
|
||||
void SetBox2D(const Bnd_Box2d& aBox2D) {
|
||||
myBox2D=aBox2D;
|
||||
};
|
||||
//
|
||||
const Bnd_Box2d& Box2D()const {
|
||||
return myBox2D;
|
||||
};
|
||||
//
|
||||
void SetIsHole(const Standard_Boolean bFlag) {
|
||||
myIsHole=bFlag;
|
||||
};
|
||||
//
|
||||
Standard_Boolean IsHole()const {
|
||||
return myIsHole;
|
||||
};
|
||||
//
|
||||
protected:
|
||||
Standard_Boolean myIsHole;
|
||||
TopoDS_Shape myShape;
|
||||
Bnd_Box2d myBox2D;
|
||||
};
|
||||
//
|
||||
typedef NCollection_IndexedDataMap
|
||||
<Standard_Integer,
|
||||
BOPAlgo_ShapeBox2D,
|
||||
TColStd_MapIntegerHasher> BOPAlgo_IndexedDataMapOfIntegerShapeBox2D;
|
||||
|
||||
typedef NCollection_IndexedDataMap
|
||||
<TopoDS_Shape,
|
||||
TopoDS_Shape,
|
||||
TopTools_ShapeMapHasher> BOPCol_IndexedDataMapOfShapeShape;
|
||||
//
|
||||
//=======================================================================
|
||||
//function :
|
||||
//purpose :
|
||||
@@ -380,198 +436,239 @@ void BOPAlgo_BuilderFace::PerformLoops()
|
||||
//=======================================================================
|
||||
void BOPAlgo_BuilderFace::PerformAreas()
|
||||
{
|
||||
myAreas.Clear();
|
||||
BRep_Builder aBB;
|
||||
// Location of the myFace
|
||||
Standard_Boolean bIsGrowth, bIsHole;
|
||||
Standard_Integer k, aNbS, aNbHoles, aNbDMISB, m, aNbMSH, aNbInOutMap;
|
||||
Standard_Real aTol;
|
||||
TopLoc_Location aLoc;
|
||||
// Get surface from myFace
|
||||
const Handle(Geom_Surface)& aS = BRep_Tool::Surface(myFace, aLoc);
|
||||
// Get tolerance of myFace
|
||||
Standard_Real aTol = BRep_Tool::Tolerance(myFace);
|
||||
|
||||
// Check if there are no loops at all
|
||||
if (myLoops.IsEmpty())
|
||||
{
|
||||
if (myContext->IsInfiniteFace(myFace))
|
||||
{
|
||||
Handle(Geom_Surface) aS;
|
||||
BRep_Builder aBB;
|
||||
TopoDS_Face aFace;
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI;
|
||||
BOPCol_IndexedMapOfShape aMHE;
|
||||
BOPCol_ListIteratorOfListOfShape aIt1;
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
|
||||
BOPCol_IndexedDataMapOfShapeShape aInOutMap;
|
||||
BOPAlgo_IndexedDataMapOfIntegerShapeBox2D aDMISB(100);
|
||||
//
|
||||
BOPCol_Box2DBndTreeSelector aSelector;
|
||||
BOPCol_Box2DBndTree aBBTree;
|
||||
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller(aBBTree);
|
||||
//
|
||||
aNbHoles=0;
|
||||
//
|
||||
aTol=BRep_Tool::Tolerance(myFace);
|
||||
aS=BRep_Tool::Surface(myFace, aLoc);
|
||||
//
|
||||
myAreas.Clear();
|
||||
//
|
||||
if (myLoops.IsEmpty()) {
|
||||
if (myContext->IsInfiniteFace(myFace)) {
|
||||
aBB.MakeFace(aFace, aS, aLoc, aTol);
|
||||
if (BRep_Tool::NaturalRestriction(myFace))
|
||||
if (BRep_Tool::NaturalRestriction(myFace)) {
|
||||
aBB.NaturalRestriction(aFace, Standard_True);
|
||||
}
|
||||
myAreas.Append(aFace);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// The new faces
|
||||
BOPCol_ListOfShape aNewFaces;
|
||||
// The hole faces which has to be classified relatively new faces
|
||||
BOPCol_IndexedMapOfShape aHoleFaces;
|
||||
// Map of the edges of the hole faces for quick check of the growths.
|
||||
// If the analyzed wire contains any of the edges from the hole faces
|
||||
// it is considered as growth.
|
||||
BOPCol_IndexedMapOfShape aMHE;
|
||||
|
||||
// Analyze the new wires - classify them to be the holes and growths
|
||||
BOPCol_ListIteratorOfListOfShape aItLL(myLoops);
|
||||
for (; aItLL.More(); aItLL.Next())
|
||||
{
|
||||
const TopoDS_Shape& aWire = aItLL.Value();
|
||||
|
||||
TopoDS_Face aFace;
|
||||
//
|
||||
// 1. Growthes and Holes -> aDMISB: [Index/ShapeBox2D]
|
||||
aIt1.Initialize(myLoops);
|
||||
for (k=0 ; aIt1.More(); aIt1.Next(), ++k) {
|
||||
Bnd_Box2d aBox2D;
|
||||
//
|
||||
const TopoDS_Shape& aWire=aIt1.Value();
|
||||
//
|
||||
aBB.MakeFace(aFace, aS, aLoc, aTol);
|
||||
aBB.Add (aFace, aWire);
|
||||
|
||||
Standard_Boolean bIsGrowth = IsGrowthWire(aWire, aMHE);
|
||||
if (!bIsGrowth)
|
||||
{
|
||||
// Fast check did not give the result, run classification
|
||||
BRepTools::AddUVBounds(aFace, aBox2D);
|
||||
//
|
||||
bIsGrowth=IsGrowthWire(aWire, aMHE);
|
||||
if (bIsGrowth) {
|
||||
bIsHole=Standard_False;
|
||||
}
|
||||
else{
|
||||
// check if a wire is a hole
|
||||
IntTools_FClass2d& aClsf=myContext->FClass2d(aFace);
|
||||
bIsGrowth = !aClsf.IsHole();
|
||||
}
|
||||
|
||||
// Save the face
|
||||
if (bIsGrowth)
|
||||
{
|
||||
aNewFaces.Append(aFace);
|
||||
}
|
||||
else
|
||||
{
|
||||
aHoleFaces.Add(aFace);
|
||||
aClsf.Init(aFace, aTol);
|
||||
//
|
||||
bIsHole=aClsf.IsHole();
|
||||
if (bIsHole) {
|
||||
BOPTools::MapShapes(aWire, TopAbs_EDGE, aMHE);
|
||||
}
|
||||
}
|
||||
|
||||
if (aHoleFaces.IsEmpty())
|
||||
{
|
||||
// No holes, stop the analysis
|
||||
myAreas.Append(aNewFaces);
|
||||
}
|
||||
|
||||
// Classify holes relatively faces
|
||||
|
||||
// Prepare tree filler with the boxes of the hole faces
|
||||
BOPCol_Box2DBndTree aBBTree;
|
||||
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller(aBBTree);
|
||||
|
||||
Standard_Integer i, aNbH = aHoleFaces.Extent();
|
||||
for (i = 1; i <= aNbH; ++i)
|
||||
{
|
||||
const TopoDS_Face& aHFace = TopoDS::Face(aHoleFaces(i));
|
||||
//
|
||||
Bnd_Box2d aBox;
|
||||
BRepTools::AddUVBounds(aHFace, aBox);
|
||||
aTreeFiller.Add(i, aBox);
|
||||
bIsHole=Standard_True;
|
||||
}
|
||||
|
||||
// Shake TreeFiller
|
||||
else {
|
||||
bIsHole=Standard_False;
|
||||
}
|
||||
}
|
||||
//
|
||||
BOPAlgo_ShapeBox2D aSB2D;
|
||||
//
|
||||
aSB2D.SetShape(aFace);
|
||||
aSB2D.SetBox2D(aBox2D);
|
||||
aSB2D.SetIsHole(bIsHole);
|
||||
//
|
||||
aDMISB.Add(k, aSB2D);
|
||||
}// for (k=0 ; aIt1.More(); aIt1.Next(), ++k) {
|
||||
//
|
||||
// 2. Prepare TreeFiller
|
||||
aNbDMISB=aDMISB.Extent();
|
||||
for (m=1; m<=aNbDMISB; ++m) {
|
||||
k=aDMISB.FindKey(m);
|
||||
const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
|
||||
//
|
||||
bIsHole=aSB2D.IsHole();
|
||||
if (bIsHole) {
|
||||
const Bnd_Box2d& aBox2D=aSB2D.Box2D();
|
||||
aTreeFiller.Add(k, aBox2D);
|
||||
++aNbHoles;
|
||||
}
|
||||
}
|
||||
//
|
||||
// 3. Shake TreeFiller
|
||||
aTreeFiller.Fill();
|
||||
|
||||
// Find outer growth face that is most close to each hole face
|
||||
BOPCol_IndexedDataMapOfShapeShape aHoleFaceMap;
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItLS(aNewFaces);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Face& aFace = TopoDS::Face(aItLS.Value());
|
||||
|
||||
// Build box
|
||||
Bnd_Box2d aBox;
|
||||
BRepTools::AddUVBounds(aFace, aBox);
|
||||
|
||||
BOPCol_Box2DBndTreeSelector aSelector;
|
||||
aSelector.SetBox(aBox);
|
||||
aBBTree.Select(aSelector);
|
||||
|
||||
const BOPCol_ListOfInteger& aLI = aSelector.Indices();
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI(aLI);
|
||||
for (; aItLI.More(); aItLI.Next())
|
||||
{
|
||||
Standard_Integer k = aItLI.Value();
|
||||
const TopoDS_Shape& aHole = aHoleFaces(k);
|
||||
// Check if it is inside
|
||||
if (!IsInside(aHole, aFace, myContext))
|
||||
continue;
|
||||
|
||||
// Save the relation
|
||||
TopoDS_Shape* pFaceWas = aHoleFaceMap.ChangeSeek(aHole);
|
||||
if (pFaceWas)
|
||||
{
|
||||
if (IsInside(aFace, *pFaceWas, myContext))
|
||||
{
|
||||
*pFaceWas = aFace;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aHoleFaceMap.Add(aHole, aFace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make the back map from faces to holes
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aFaceHolesMap;
|
||||
|
||||
aNbH = aHoleFaceMap.Extent();
|
||||
for (i = 1; i <= aNbH; ++i)
|
||||
{
|
||||
const TopoDS_Shape& aHole = aHoleFaceMap.FindKey(i);
|
||||
const TopoDS_Shape& aFace = aHoleFaceMap(i);
|
||||
//
|
||||
BOPCol_ListOfShape* pLHoles = aFaceHolesMap.ChangeSeek(aFace);
|
||||
if (!pLHoles)
|
||||
pLHoles = &aFaceHolesMap(aFaceHolesMap.Add(aFace, BOPCol_ListOfShape()));
|
||||
pLHoles->Append(aHole);
|
||||
// 4. Find outer growth shell that is most close
|
||||
// to each hole shell
|
||||
for (m=1; m<=aNbDMISB; ++m) {
|
||||
const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
|
||||
bIsHole=aSB2D.IsHole();
|
||||
if (bIsHole) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add unused holes to the original face
|
||||
if (aHoleFaces.Extent() != aHoleFaceMap.Extent())
|
||||
{
|
||||
//
|
||||
const Bnd_Box2d& aBox2DF=aSB2D.Box2D();
|
||||
const TopoDS_Shape aF=aSB2D.Shape();
|
||||
//
|
||||
aSelector.Clear();
|
||||
aSelector.SetBox(aBox2DF);
|
||||
//
|
||||
aNbS = aBBTree.Select(aSelector);
|
||||
if (!aNbS) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
|
||||
//
|
||||
aItLI.Initialize(aLI);
|
||||
for (; aItLI.More(); aItLI.Next()) {
|
||||
k=aItLI.Value();
|
||||
const BOPAlgo_ShapeBox2D& aSB2Dk=aDMISB.FindFromKey(k);
|
||||
const TopoDS_Shape& aHole=aSB2Dk.Shape();
|
||||
//
|
||||
if (!IsInside(aHole, aF, myContext)){
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (aInOutMap.Contains(aHole)){
|
||||
TopoDS_Shape& aF2=aInOutMap.ChangeFromKey(aHole);
|
||||
if (IsInside(aF, aF2, myContext)) {
|
||||
aF2=aF;
|
||||
}
|
||||
}
|
||||
else{
|
||||
aInOutMap.Add(aHole, aF);
|
||||
}
|
||||
}
|
||||
}// for (m=1; m<=aNbDMISB; ++m)
|
||||
//
|
||||
// 5.1 Map [Face/Holes] -> aMSH
|
||||
aNbInOutMap=aInOutMap.Extent();
|
||||
for (m=1; m<=aNbInOutMap; ++m) {
|
||||
const TopoDS_Shape& aHole=aInOutMap.FindKey(m);
|
||||
const TopoDS_Shape& aF=aInOutMap.FindFromIndex(m);
|
||||
//
|
||||
if (aMSH.Contains(aF)) {
|
||||
BOPCol_ListOfShape& aLH=aMSH.ChangeFromKey(aF);
|
||||
aLH.Append(aHole);
|
||||
}
|
||||
else {
|
||||
BOPCol_ListOfShape aLH;
|
||||
aLH.Append(aHole);
|
||||
aMSH.Add(aF, aLH);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 5.2. Add unused holes to the original face
|
||||
if (aNbHoles != aNbInOutMap) {
|
||||
Bnd_Box aBoxF;
|
||||
BRepBndLib::Add(myFace, aBoxF);
|
||||
if (aBoxF.IsOpenXmin() || aBoxF.IsOpenXmax() ||
|
||||
aBoxF.IsOpenYmin() || aBoxF.IsOpenYmax() ||
|
||||
aBoxF.IsOpenZmin() || aBoxF.IsOpenZmax())
|
||||
{
|
||||
TopoDS_Face aFace;
|
||||
aBB.MakeFace(aFace, aS, aLoc, aTol);
|
||||
BOPCol_ListOfShape& anUnUsedHoles = aFaceHolesMap(aFaceHolesMap.Add(aFace, BOPCol_ListOfShape()));
|
||||
aNbH = aHoleFaces.Extent();
|
||||
for (i = 1; i <= aNbH; ++i)
|
||||
{
|
||||
const TopoDS_Shape& aHole = aHoleFaces(i);
|
||||
if (!aHoleFaceMap.Contains(aHole))
|
||||
aBoxF.IsOpenZmin() || aBoxF.IsOpenZmax()) {
|
||||
//
|
||||
BOPCol_ListOfShape anUnUsedHoles;
|
||||
for (m = 1; m <= aNbDMISB; ++m) {
|
||||
const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
|
||||
if (aSB2D.IsHole()) {
|
||||
const TopoDS_Shape& aHole = aSB2D.Shape();
|
||||
if (!aInOutMap.Contains(aHole)) {
|
||||
anUnUsedHoles.Append(aHole);
|
||||
}
|
||||
// Save it
|
||||
aNewFaces.Append(aFace);
|
||||
}
|
||||
}
|
||||
|
||||
// Add Holes to Faces and add them to myAreas
|
||||
aItLS.Initialize(aNewFaces);
|
||||
for ( ; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
TopoDS_Face& aFace = *(TopoDS_Face*)&aItLS.Value();
|
||||
const BOPCol_ListOfShape* pLHoles = aFaceHolesMap.Seek(aFace);
|
||||
if (pLHoles)
|
||||
{
|
||||
// update faces with the holes
|
||||
BOPCol_ListIteratorOfListOfShape aItLH(*pLHoles);
|
||||
for (; aItLH.More(); aItLH.Next())
|
||||
{
|
||||
const TopoDS_Shape& aFHole = aItLH.Value();
|
||||
// The hole face contains only one wire
|
||||
TopoDS_Iterator aItW(aFHole);
|
||||
aBB.Add(aFace, aItW.Value());
|
||||
//
|
||||
if (anUnUsedHoles.Extent()) {
|
||||
aBB.MakeFace(aFace, aS, aLoc, aTol);
|
||||
aMSH.Add(aFace, anUnUsedHoles);
|
||||
//
|
||||
BOPAlgo_ShapeBox2D aSB2D;
|
||||
//
|
||||
aSB2D.SetShape(aFace);
|
||||
aSB2D.SetIsHole(Standard_False);
|
||||
//
|
||||
aDMISB.Add(aNbDMISB, aSB2D);
|
||||
++aNbDMISB;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//
|
||||
// 6. Add aHoles to Faces
|
||||
aNbMSH=aMSH.Extent();
|
||||
for (m=1; m<=aNbMSH; ++m) {
|
||||
TopoDS_Face aF=(*(TopoDS_Face *)(&aMSH.FindKey(m)));
|
||||
const BOPCol_ListOfShape& aLH=aMSH.FindFromIndex(m);
|
||||
//
|
||||
aIt1.Initialize(aLH);
|
||||
for (; aIt1.More(); aIt1.Next()) {
|
||||
TopoDS_Shape aWHole;
|
||||
//
|
||||
const TopoDS_Shape& aFHole=aIt1.Value();
|
||||
GetWire(aFHole, aWHole);
|
||||
aBB.Add (aF, aWHole);
|
||||
}
|
||||
//
|
||||
// update classifier
|
||||
myContext->FClass2d(aFace).Init(aFace, aTol);
|
||||
aTol=BRep_Tool::Tolerance(aF);
|
||||
IntTools_FClass2d& aClsf=myContext->FClass2d(aF);
|
||||
aClsf.Init(aF, aTol);
|
||||
}
|
||||
|
||||
// The face is just a draft that does not contain any internal shapes
|
||||
myAreas.Append(aFace);
|
||||
//
|
||||
// 7. Fill myAreas
|
||||
// NB:These aNewFaces are draft faces that
|
||||
// do not contain any internal shapes
|
||||
for (m=1; m<=aNbDMISB; ++m) {
|
||||
const BOPAlgo_ShapeBox2D& aSB2D=aDMISB.FindFromIndex(m);
|
||||
bIsHole=aSB2D.IsHole();
|
||||
if (!bIsHole) {
|
||||
const TopoDS_Shape aF=aSB2D.Shape();
|
||||
myAreas.Append(aF);
|
||||
}
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : GetWire
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void GetWire(const TopoDS_Shape& aF, TopoDS_Shape& aW)
|
||||
{
|
||||
TopoDS_Shape aWx;
|
||||
TopoDS_Iterator aIt;
|
||||
//
|
||||
aIt.Initialize(aF);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
aW=aIt.Value();
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
@@ -754,14 +851,18 @@ Standard_Boolean IsInside(const TopoDS_Shape& theHole,
|
||||
Standard_Boolean IsGrowthWire(const TopoDS_Shape& theWire,
|
||||
const BOPCol_IndexedMapOfShape& theMHE)
|
||||
{
|
||||
if (theMHE.Extent())
|
||||
{
|
||||
TopoDS_Iterator aIt(theWire);
|
||||
for(; aIt.More(); aIt.Next())
|
||||
{
|
||||
if (theMHE.Contains(aIt.Value()))
|
||||
return Standard_True;
|
||||
Standard_Boolean bRet;
|
||||
TopoDS_Iterator aIt;
|
||||
//
|
||||
bRet=Standard_False;
|
||||
if (theMHE.Extent()) {
|
||||
aIt.Initialize(theWire);
|
||||
for(; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aE=aIt.Value();
|
||||
if (theMHE.Contains(aE)) {
|
||||
return !bRet;
|
||||
}
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
@@ -77,6 +77,57 @@ static
|
||||
void MakeInternalShells(const BOPCol_IndexedMapOfShape& ,
|
||||
BOPCol_ListOfShape& );
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_BuilderSolid_ShapeBox
|
||||
//purpose : Auxiliary class
|
||||
//=======================================================================
|
||||
class BOPAlgo_BuilderSolid_ShapeBox {
|
||||
public:
|
||||
BOPAlgo_BuilderSolid_ShapeBox() {
|
||||
myIsHole=Standard_False;
|
||||
};
|
||||
//
|
||||
~BOPAlgo_BuilderSolid_ShapeBox() {
|
||||
};
|
||||
//
|
||||
void SetShape(const TopoDS_Shape& aS) {
|
||||
myShape=aS;
|
||||
};
|
||||
//
|
||||
const TopoDS_Shape& Shape()const {
|
||||
return myShape;
|
||||
};
|
||||
//
|
||||
void SetBox(const Bnd_Box& aBox) {
|
||||
myBox=aBox;
|
||||
};
|
||||
//
|
||||
const Bnd_Box& Box()const {
|
||||
return myBox;
|
||||
};
|
||||
//
|
||||
void SetIsHole(const Standard_Boolean bFlag) {
|
||||
myIsHole=bFlag;
|
||||
};
|
||||
//
|
||||
Standard_Boolean IsHole()const {
|
||||
return myIsHole;
|
||||
};
|
||||
//
|
||||
protected:
|
||||
Standard_Boolean myIsHole;
|
||||
TopoDS_Shape myShape;
|
||||
Bnd_Box myBox;
|
||||
};
|
||||
//
|
||||
typedef NCollection_DataMap
|
||||
<Standard_Integer,
|
||||
BOPAlgo_BuilderSolid_ShapeBox,
|
||||
TColStd_MapIntegerHasher> BOPAlgo_DataMapOfIntegerBSSB;
|
||||
//
|
||||
typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator
|
||||
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB;
|
||||
//
|
||||
//=======================================================================
|
||||
//function : BOPAlgo_FacePnt
|
||||
//purpose :
|
||||
@@ -249,9 +300,6 @@ void BOPAlgo_BuilderSolid::Perform()
|
||||
{
|
||||
GetReport()->Clear();
|
||||
//
|
||||
if (myShapes.IsEmpty())
|
||||
return;
|
||||
|
||||
if (myContext.IsNull()) {
|
||||
myContext=new IntTools_Context;
|
||||
}
|
||||
@@ -524,158 +572,178 @@ void BOPAlgo_BuilderSolid::PerformLoops()
|
||||
//=======================================================================
|
||||
void BOPAlgo_BuilderSolid::PerformAreas()
|
||||
{
|
||||
myAreas.Clear();
|
||||
Standard_Boolean bIsGrowth, bIsHole;
|
||||
Standard_Integer i, k, aNbInOut, aNbMSH;
|
||||
BRep_Builder aBB;
|
||||
// The new solids
|
||||
BOPCol_ListOfShape aNewSolids;
|
||||
// The hole shells which has to be classified relatively new solids
|
||||
BOPCol_IndexedMapOfShape aHoleShells;
|
||||
// Map of the faces of the hole shells for quick check of the growths.
|
||||
// If the analyzed shell contains any of the hole faces, it is considered as growth.
|
||||
BOPCol_ListIteratorOfListOfShape aItLS;
|
||||
BOPCol_ListOfShape aNewSolids, aHoleShells;
|
||||
BOPCol_IndexedDataMapOfShapeShape aInOutMap;
|
||||
BOPCol_IndexedMapOfShape aMHF;
|
||||
|
||||
// Analyze the shells
|
||||
BOPCol_ListIteratorOfListOfShape aItLL(myLoops);
|
||||
for (; aItLL.More(); aItLL.Next())
|
||||
{
|
||||
const TopoDS_Shape& aShell = aItLL.Value();
|
||||
|
||||
Standard_Boolean bIsGrowth = IsGrowthShell(aShell, aMHF);
|
||||
if (!bIsGrowth)
|
||||
{
|
||||
// Fast check did not give the result, run classification
|
||||
bIsGrowth = !IsHole(aShell, myContext);
|
||||
}
|
||||
|
||||
// Save the solid
|
||||
if (bIsGrowth)
|
||||
{
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI;
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
BOPCol_BoxBndTree aBBTree;
|
||||
NCollection_UBTreeFiller
|
||||
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
|
||||
BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
|
||||
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
|
||||
//
|
||||
myAreas.Clear();
|
||||
//
|
||||
// Draft solids [aNewSolids]
|
||||
aItLS.Initialize(myLoops);
|
||||
for (k=0; aItLS.More(); aItLS.Next(), ++k) {
|
||||
TopoDS_Solid aSolid;
|
||||
Bnd_Box aBox;
|
||||
BOPAlgo_BuilderSolid_ShapeBox aSB;
|
||||
//
|
||||
const TopoDS_Shape& aShell = aItLS.Value();
|
||||
aSB.SetShape(aShell);
|
||||
//
|
||||
BRepBndLib::Add(aShell, aBox);
|
||||
bIsHole=Standard_False;
|
||||
//
|
||||
bIsGrowth=IsGrowthShell(aShell, aMHF);
|
||||
if (bIsGrowth) {
|
||||
// make a growth solid from a shell
|
||||
aBB.MakeSolid(aSolid);
|
||||
aBB.Add (aSolid, aShell);
|
||||
//
|
||||
aNewSolids.Append (aSolid);
|
||||
aSB.SetShape(aSolid);
|
||||
}
|
||||
else
|
||||
{
|
||||
aHoleShells.Add(aShell);
|
||||
else{
|
||||
// check if a shell is a hole
|
||||
bIsHole=IsHole(aShell, myContext);
|
||||
if (bIsHole) {
|
||||
aHoleShells.Append(aShell);
|
||||
BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
|
||||
aSB.SetShape(aShell);
|
||||
}
|
||||
}
|
||||
|
||||
if (aHoleShells.IsEmpty())
|
||||
{
|
||||
// No holes, stop the analysis
|
||||
myAreas.Append(aNewSolids);
|
||||
return;
|
||||
}
|
||||
|
||||
// Classify holes relatively solids
|
||||
|
||||
// Prepare tree filler with the boxes of the hole shells
|
||||
BOPCol_BoxBndTree aBBTree;
|
||||
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
|
||||
|
||||
Standard_Integer i, aNbH = aHoleShells.Extent();
|
||||
for (i = 1; i <= aNbH; ++i)
|
||||
{
|
||||
const TopoDS_Shape& aHShell = aHoleShells(i);
|
||||
else {
|
||||
// make a growth solid from a shell
|
||||
aBB.MakeSolid(aSolid);
|
||||
aBB.Add (aSolid, aShell);
|
||||
//
|
||||
Bnd_Box aBox;
|
||||
BRepBndLib::Add(aHShell, aBox);
|
||||
aTreeFiller.Add(i, aBox);
|
||||
aNewSolids.Append (aSolid);
|
||||
aSB.SetShape(aSolid);
|
||||
}
|
||||
|
||||
// Shake TreeFiller
|
||||
}
|
||||
//
|
||||
aSB.SetBox(aBox);
|
||||
aSB.SetIsHole(bIsHole);
|
||||
aDMISB.Bind(k, aSB);
|
||||
}
|
||||
//
|
||||
// 2. Prepare TreeFiller
|
||||
aItDMISB.Initialize(aDMISB);
|
||||
for (; aItDMISB.More(); aItDMISB.Next()) {
|
||||
k=aItDMISB.Key();
|
||||
const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
|
||||
//
|
||||
bIsHole=aSB.IsHole();
|
||||
if (bIsHole) {
|
||||
const Bnd_Box& aBox=aSB.Box();
|
||||
aTreeFiller.Add(k, aBox);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 3. Shake TreeFiller
|
||||
aTreeFiller.Fill();
|
||||
|
||||
// Find outer growth shell that is most close to each hole shell
|
||||
BOPCol_IndexedDataMapOfShapeShape aHoleSolidMap;
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItLS(aNewSolids);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
const TopoDS_Shape& aSolid = aItLS.Value();
|
||||
|
||||
// Build box
|
||||
Bnd_Box aBox;
|
||||
BRepBndLib::Add(aSolid, aBox);
|
||||
|
||||
BOPCol_BoxBndTreeSelector aSelector;
|
||||
aSelector.SetBox(aBox);
|
||||
aBBTree.Select(aSelector);
|
||||
|
||||
const BOPCol_ListOfInteger& aLI = aSelector.Indices();
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI(aLI);
|
||||
for (; aItLI.More(); aItLI.Next())
|
||||
{
|
||||
Standard_Integer k = aItLI.Value();
|
||||
const TopoDS_Shape& aHole = aHoleShells(k);
|
||||
// Check if it is inside
|
||||
if (!IsInside(aHole, aSolid, myContext))
|
||||
continue;
|
||||
|
||||
// Save the relation
|
||||
TopoDS_Shape* pSolidWas = aHoleSolidMap.ChangeSeek(aHole);
|
||||
if (pSolidWas)
|
||||
{
|
||||
if (IsInside(aSolid, *pSolidWas, myContext))
|
||||
{
|
||||
*pSolidWas = aSolid;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aHoleSolidMap.Add(aHole, aSolid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make the back map from solids to holes
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aSolidHolesMap;
|
||||
|
||||
aNbH = aHoleSolidMap.Extent();
|
||||
for (i = 1; i <= aNbH; ++i)
|
||||
{
|
||||
const TopoDS_Shape& aHole = aHoleSolidMap.FindKey(i);
|
||||
const TopoDS_Shape& aSolid = aHoleSolidMap(i);
|
||||
//
|
||||
BOPCol_ListOfShape* pLHoles = aSolidHolesMap.ChangeSeek(aSolid);
|
||||
if (!pLHoles)
|
||||
pLHoles = &aSolidHolesMap(aSolidHolesMap.Add(aSolid, BOPCol_ListOfShape()));
|
||||
pLHoles->Append(aHole);
|
||||
// 4. Find outer growth shell that is most close
|
||||
// to each hole shell
|
||||
aItDMISB.Initialize(aDMISB);
|
||||
for (; aItDMISB.More(); aItDMISB.Next()) {
|
||||
k=aItDMISB.Key();
|
||||
const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
|
||||
bIsHole=aSB.IsHole();
|
||||
if (bIsHole) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add Holes to Solids and add them to myAreas
|
||||
aItLS.Initialize(aNewSolids);
|
||||
for ( ; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
TopoDS_Solid& aSolid = *(TopoDS_Solid*)&aItLS.Value();
|
||||
const BOPCol_ListOfShape* pLHoles = aSolidHolesMap.Seek(aSolid);
|
||||
if (pLHoles)
|
||||
{
|
||||
// update solid
|
||||
BOPCol_ListIteratorOfListOfShape aItLH(*pLHoles);
|
||||
for (; aItLH.More(); aItLH.Next())
|
||||
{
|
||||
const TopoDS_Shape& aHole = aItLH.Value();
|
||||
//
|
||||
const TopoDS_Shape aSolid=aSB.Shape();
|
||||
const Bnd_Box& aBoxSolid=aSB.Box();
|
||||
//
|
||||
aSelector.Clear();
|
||||
aSelector.SetBox(aBoxSolid);
|
||||
//
|
||||
aBBTree.Select(aSelector);
|
||||
//
|
||||
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
|
||||
//
|
||||
aItLI.Initialize(aLI);
|
||||
for (; aItLI.More(); aItLI.Next()) {
|
||||
k=aItLI.Value();
|
||||
const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k);
|
||||
const TopoDS_Shape& aHole=aSBk.Shape();
|
||||
//
|
||||
if (!IsInside(aHole, aSolid, myContext)){
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (aInOutMap.Contains (aHole)){
|
||||
const TopoDS_Shape& aSolidWas = aInOutMap.FindFromKey(aHole);
|
||||
if (IsInside(aSolid, aSolidWas, myContext)) {
|
||||
aInOutMap.ChangeFromKey(aHole) = aSolid;
|
||||
}
|
||||
}
|
||||
else{
|
||||
aInOutMap.Add(aHole, aSolid);
|
||||
}
|
||||
}
|
||||
}//for (i = 1; i <= aNbDMISB; ++i) {
|
||||
//
|
||||
// 5. Map [Solid/Holes] -> aMSH
|
||||
aNbInOut = aInOutMap.Extent();
|
||||
for (i = 1; i <= aNbInOut; ++i) {
|
||||
const TopoDS_Shape& aHole = aInOutMap.FindKey(i);
|
||||
const TopoDS_Shape& aSolid = aInOutMap(i);
|
||||
//
|
||||
if (aMSH.Contains(aSolid)) {
|
||||
BOPCol_ListOfShape& aLH = aMSH.ChangeFromKey(aSolid);
|
||||
aLH.Append(aHole);
|
||||
}
|
||||
else {
|
||||
BOPCol_ListOfShape aLH;
|
||||
aLH.Append(aHole);
|
||||
aMSH.Add(aSolid, aLH);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 6. Add aHoles to Solids
|
||||
aNbMSH = aMSH.Extent();
|
||||
for (i = 1; i <= aNbMSH; ++i) {
|
||||
TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&(aMSH.FindKey(i))));
|
||||
const BOPCol_ListOfShape& aLH = aMSH(i);
|
||||
//
|
||||
aItLS.Initialize(aLH);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aHole = aItLS.Value();
|
||||
aBB.Add (aSolid, aHole);
|
||||
}
|
||||
|
||||
//
|
||||
// update classifier
|
||||
myContext->SolidClassifier(aSolid).Load(aSolid);
|
||||
BRepClass3d_SolidClassifier& aSC=
|
||||
myContext->SolidClassifier(aSolid);
|
||||
aSC.Load(aSolid);
|
||||
//
|
||||
}
|
||||
|
||||
myAreas.Append(aSolid);
|
||||
//
|
||||
// 7. These aNewSolids are draft solids that
|
||||
// do not contain any internal shapes
|
||||
aItLS.Initialize(aNewSolids);
|
||||
for ( ; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aSx=aItLS.Value();
|
||||
myAreas.Append(aSx);
|
||||
}
|
||||
|
||||
// Add holes that outside the solids to myAreas
|
||||
aNbH = aHoleShells.Extent();
|
||||
for (i = 1; i <= aNbH; ++i)
|
||||
{
|
||||
const TopoDS_Shape& aHole = aHoleShells(i);
|
||||
if (!aHoleSolidMap.Contains(aHole))
|
||||
{
|
||||
aItLS.Initialize(aHoleShells);
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aHole = aItLS.Value();
|
||||
if (!aInOutMap.Contains(aHole)){
|
||||
TopoDS_Solid aSolid;
|
||||
//
|
||||
aBB.MakeSolid(aSolid);
|
||||
aBB.Add (aSolid, aHole);
|
||||
//
|
||||
@@ -1005,14 +1073,18 @@ Standard_Boolean IsInside(const TopoDS_Shape& theS1,
|
||||
Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
|
||||
const BOPCol_IndexedMapOfShape& theMHF)
|
||||
{
|
||||
if (theMHF.Extent())
|
||||
{
|
||||
TopoDS_Iterator aIt(theShell);
|
||||
for(; aIt.More(); aIt.Next())
|
||||
{
|
||||
if (theMHF.Contains(aIt.Value()))
|
||||
return Standard_True;
|
||||
Standard_Boolean bRet;
|
||||
TopoDS_Iterator aIt;
|
||||
//
|
||||
bRet=Standard_False;
|
||||
if (theMHF.Extent()) {
|
||||
aIt.Initialize(theShell);
|
||||
for(; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aF=aIt.Value();
|
||||
if (theMHF.Contains(aF)) {
|
||||
return !bRet;
|
||||
}
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
@@ -51,7 +51,6 @@
|
||||
#include <Precision.hxx>
|
||||
#include <IntTools_Context.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
@@ -63,11 +62,6 @@ static
|
||||
Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
|
||||
const BOPDS_FaceInfo& aFI2);
|
||||
//
|
||||
static
|
||||
TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
|
||||
const BOPCol_DataMapOfShapeListOfShape& theImages,
|
||||
Handle(IntTools_Context)& theCtx);
|
||||
//
|
||||
typedef BOPCol_NCVector<TopoDS_Shape> BOPAlgo_VectorOfShape;
|
||||
//
|
||||
typedef BOPCol_NCVector<BOPAlgo_VectorOfShape> \
|
||||
@@ -246,6 +240,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
|
||||
{
|
||||
Standard_Boolean bHasFaceInfo, bIsClosed, bIsDegenerated, bToReverse;
|
||||
Standard_Integer i, j, k, aNbS, aNbPBIn, aNbPBOn, aNbPBSc, aNbAV, nSp;
|
||||
Standard_Size aNbBF;
|
||||
TopoDS_Face aFF, aFSD;
|
||||
TopoDS_Edge aSp, aEE;
|
||||
TopAbs_Orientation anOriF, anOriE;
|
||||
@@ -254,6 +249,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
|
||||
BOPCol_ListOfInteger aLIAV;
|
||||
BOPCol_MapOfShape aMFence;
|
||||
Handle(NCollection_BaseAllocator) aAllocator;
|
||||
BOPCol_ListOfShape aLFIm(myAllocator);
|
||||
BOPAlgo_VectorOfBuilderFace aVBF;
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope f
|
||||
@@ -263,10 +259,6 @@ void BOPAlgo_Builder::BuildSplitFaces()
|
||||
BOPCol_ListOfShape aLE(aAllocator);
|
||||
BOPCol_MapOfShape aMDE(100, aAllocator);
|
||||
//
|
||||
// Build temporary map of faces images to avoid rebuilding
|
||||
// of the faces without any IN or section edges
|
||||
NCollection_IndexedDataMap<Standard_Integer, BOPCol_ListOfShape> aFacesIm;
|
||||
//
|
||||
aNbS=myDS->NbSourceShapes();
|
||||
//
|
||||
for (i=0; i<aNbS; ++i) {
|
||||
@@ -300,32 +292,17 @@ void BOPAlgo_Builder::BuildSplitFaces()
|
||||
if (!aNbPBIn && !aNbPBOn && !aNbPBSc && !aNbAV) { // not compete
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!aNbPBIn && !aNbPBSc)
|
||||
{
|
||||
// No internal parts for the face, so just build the draft face
|
||||
// and keep it to pass directly into result.
|
||||
// If the original face has any internal edges, the draft face
|
||||
// will be null, as the internal edges may split the face on parts
|
||||
// (as in the case "bugs modalg_5 bug25245_1").
|
||||
// The BuilderFace algorithm will be called in this case.
|
||||
TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext);
|
||||
if (!aFD.IsNull())
|
||||
{
|
||||
aFacesIm(aFacesIm.Add(i, BOPCol_ListOfShape())).Append(aFD);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
aMFence.Clear();
|
||||
//
|
||||
anOriF=aF.Orientation();
|
||||
aFF=aF;
|
||||
aFF.Orientation(TopAbs_FORWARD);
|
||||
//
|
||||
// 1. Fill the edges set for the face aFF -> LE
|
||||
// 1. Fill the egdes set for the face aFF -> LE
|
||||
aLE.Clear();
|
||||
|
||||
//
|
||||
//
|
||||
// 1.1 Bounding edges
|
||||
aExp.Init(aFF, TopAbs_EDGE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
@@ -449,34 +426,34 @@ void BOPAlgo_Builder::BuildSplitFaces()
|
||||
//
|
||||
}// for (i=0; i<aNbS; ++i) {
|
||||
//
|
||||
aNbBF=aVBF.Extent();
|
||||
//
|
||||
//===================================================
|
||||
BOPAlgo_BuilderFaceCnt::Perform(myRunParallel, aVBF);
|
||||
//===================================================
|
||||
//
|
||||
Standard_Integer aNbBF = aVBF.Extent();
|
||||
for (k = 0; k < aNbBF; ++k)
|
||||
{
|
||||
BOPAlgo_BuilderFace& aBF = aVBF(k);
|
||||
aFacesIm.Add(myDS->Index(aBF.Face()), aBF.Areas());
|
||||
}
|
||||
|
||||
aNbBF = aFacesIm.Extent();
|
||||
for (k = 1; k <= aNbBF; ++k)
|
||||
{
|
||||
const TopoDS_Face& aF = TopoDS::Face(myDS->Shape(aFacesIm.FindKey(k)));
|
||||
anOriF = aF.Orientation();
|
||||
const BOPCol_ListOfShape& aLFR = aFacesIm(k);
|
||||
for (k=0; k<(Standard_Integer)aNbBF; ++k) {
|
||||
aLFIm.Clear();
|
||||
//
|
||||
BOPCol_ListOfShape* pLFIm = mySplits.Bound(aF, BOPCol_ListOfShape());
|
||||
BOPAlgo_BuilderFace& aBF=aVBF(k);
|
||||
TopoDS_Face aF=aBF.Face();
|
||||
anOriF=aBF.Orientation();
|
||||
aF.Orientation(anOriF);
|
||||
//
|
||||
const BOPCol_ListOfShape& aLFR=aBF.Areas();
|
||||
aIt.Initialize(aLFR);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
TopoDS_Shape& aFR=aIt.ChangeValue();
|
||||
if (anOriF==TopAbs_REVERSED)
|
||||
if (anOriF==TopAbs_REVERSED) {
|
||||
aFR.Orientation(TopAbs_REVERSED);
|
||||
pLFIm->Append(aFR);
|
||||
}
|
||||
//aFR.Orientation(anOriF);
|
||||
aLFIm.Append(aFR);
|
||||
}
|
||||
//
|
||||
mySplits.Bind(aF, aLFIm);
|
||||
}// for (k=0; k<aNbBF; ++k) {
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope t
|
||||
}
|
||||
//=======================================================================
|
||||
@@ -793,98 +770,3 @@ Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
|
||||
}
|
||||
return bRet;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : BuildDraftFace
|
||||
//purpose : Build draft faces, updating the bounding edges,
|
||||
// according to the information stored into the <theImages> map
|
||||
//=======================================================================
|
||||
TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
|
||||
const BOPCol_DataMapOfShapeListOfShape& theImages,
|
||||
Handle(IntTools_Context)& theCtx)
|
||||
{
|
||||
BRep_Builder aBB;
|
||||
// Take the information from the original face
|
||||
TopLoc_Location aLoc;
|
||||
const Handle(Geom_Surface)& aS = BRep_Tool::Surface(theFace, aLoc);
|
||||
const Standard_Real aTol = BRep_Tool::Tolerance(theFace);
|
||||
// Make the new face, without any wires
|
||||
TopoDS_Face aDraftFace;
|
||||
aBB.MakeFace(aDraftFace, aS, aLoc, aTol);
|
||||
|
||||
// Update wires of the original face and add them to draft face
|
||||
TopoDS_Iterator aItW(theFace.Oriented(TopAbs_FORWARD));
|
||||
for (; aItW.More(); aItW.Next())
|
||||
{
|
||||
const TopoDS_Shape& aW = aItW.Value();
|
||||
if (aW.ShapeType() != TopAbs_WIRE)
|
||||
continue;
|
||||
|
||||
// Rebuild wire using images of edges
|
||||
TopoDS_Iterator aItE(aW.Oriented(TopAbs_FORWARD));
|
||||
if (!aItE.More())
|
||||
continue;
|
||||
|
||||
TopoDS_Wire aNewWire;
|
||||
aBB.MakeWire(aNewWire);
|
||||
|
||||
for (; aItE.More(); aItE.Next())
|
||||
{
|
||||
const TopoDS_Edge& aE = TopoDS::Edge(aItE.Value());
|
||||
|
||||
TopAbs_Orientation anOriE = aE.Orientation();
|
||||
if (anOriE == TopAbs_INTERNAL)
|
||||
{
|
||||
// The internal edges could split the original face on halves.
|
||||
// Thus, use the BuilderFace algorithm to build the new face.
|
||||
TopoDS_Face aNull;
|
||||
return aNull;
|
||||
}
|
||||
|
||||
const BOPCol_ListOfShape* pLEIm = theImages.Seek(aE);
|
||||
if (!pLEIm)
|
||||
{
|
||||
aBB.Add(aNewWire, aE);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if the original edge is degenerated
|
||||
Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aE);
|
||||
// Check if the original edge is closed on the face
|
||||
Standard_Boolean bIsClosed = BRep_Tool::IsClosed(aE, theFace);
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItLEIm(*pLEIm);
|
||||
for (; aItLEIm.More(); aItLEIm.Next())
|
||||
{
|
||||
TopoDS_Edge& aSp = TopoDS::Edge(aItLEIm.Value());
|
||||
|
||||
aSp.Orientation(anOriE);
|
||||
if (bIsDegenerated)
|
||||
{
|
||||
aBB.Add(aNewWire, aSp);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check closeness of the split edge and if it is not
|
||||
// make the second PCurve
|
||||
if (bIsClosed && !BRep_Tool::IsClosed(aSp, theFace))
|
||||
BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, theFace);
|
||||
|
||||
// Check if the split should be reversed
|
||||
if (BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, theCtx))
|
||||
aSp.Reverse();
|
||||
|
||||
aBB.Add(aNewWire, aSp);
|
||||
}
|
||||
}
|
||||
|
||||
aNewWire.Orientation(aW.Orientation());
|
||||
aNewWire.Closed(BRep_Tool::IsClosed(aNewWire));
|
||||
aBB.Add(aDraftFace, aNewWire);
|
||||
}
|
||||
|
||||
if (theFace.Orientation() == TopAbs_REVERSED)
|
||||
aDraftFace.Reverse();
|
||||
|
||||
return aDraftFace;
|
||||
}
|
||||
|
@@ -222,11 +222,12 @@ class BOPAlgo_FillIn3DParts : public BOPAlgo_Algo {
|
||||
const Handle(NCollection_BaseAllocator)& );
|
||||
|
||||
void MakeConnexityBlock
|
||||
(const TopoDS_Face& ,
|
||||
(const BOPCol_ListOfShape& ,
|
||||
const BOPCol_IndexedMapOfShape& ,
|
||||
const BOPCol_MapOfShape& ,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& ,
|
||||
BOPCol_MapOfShape& ,
|
||||
BOPCol_ListOfShape& );
|
||||
BOPCol_ListOfShape& ,
|
||||
const Handle(NCollection_BaseAllocator)& );
|
||||
//
|
||||
protected:
|
||||
TopoDS_Solid mySolid;
|
||||
@@ -256,13 +257,14 @@ void BOPAlgo_FillIn3DParts::Perform()
|
||||
//
|
||||
Standard_Integer aNbFP, k, nFP, iIsIN;
|
||||
Standard_Real aTolPC;
|
||||
BOPCol_ListIteratorOfListOfInteger aItLI;
|
||||
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);
|
||||
@@ -332,16 +334,28 @@ void BOPAlgo_FillIn3DParts::Perform()
|
||||
iIsIN=BOPTools_AlgoTools::IsInternalFace
|
||||
(aFP, myDraftSolid, aMEF, aTolPC, myContext);
|
||||
//
|
||||
// Make connexity blocks of faces, avoiding passing through the
|
||||
// borders of the solid.
|
||||
// It helps to reduce significantly the number of classified faces.
|
||||
aLCBF.Clear();
|
||||
MakeConnexityBlock(aFP, aME, aMEFP, aMFDone, aLCBF);
|
||||
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);
|
||||
//
|
||||
if (iIsIN) {
|
||||
aItLS.Initialize(aLCBF);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
myLFIN.Append(aItLS.Value());
|
||||
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) {
|
||||
}
|
||||
@@ -365,10 +379,16 @@ void BOPAlgo_FillIn3DParts::MapEdgesAndFaces
|
||||
for (; myItW.More(); myItW.Next()) {
|
||||
const TopoDS_Shape& aE=myItW.Value();
|
||||
//
|
||||
BOPCol_ListOfShape* pLF = aMEF.ChangeSeek(aE);
|
||||
if (!pLF)
|
||||
pLF = &aMEF(aMEF.Add(aE, BOPCol_ListOfShape(theAllocator)));
|
||||
pLF->Append(aF);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -377,43 +397,83 @@ void BOPAlgo_FillIn3DParts::MapEdgesAndFaces
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPAlgo_FillIn3DParts::MakeConnexityBlock
|
||||
(const TopoDS_Face& theFStart,
|
||||
(const BOPCol_ListOfShape& theLFIn,
|
||||
const BOPCol_IndexedMapOfShape& theMEAvoid,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
|
||||
BOPCol_MapOfShape& theMFDone,
|
||||
BOPCol_ListOfShape& theLCB)
|
||||
const BOPCol_MapOfShape& aMFDone,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
|
||||
BOPCol_ListOfShape& theLCB,
|
||||
const Handle(NCollection_BaseAllocator)& theAlr)
|
||||
{
|
||||
// Add start element
|
||||
theLCB.Append(theFStart);
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItCB(theLCB);
|
||||
for (; aItCB.More(); aItCB.Next())
|
||||
{
|
||||
const TopoDS_Shape& aF = aItCB.Value();
|
||||
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())
|
||||
{
|
||||
for (; myItF.More(); myItF.Next()) {
|
||||
const TopoDS_Shape& aW=myItF.Value();
|
||||
if (aW.ShapeType() != TopAbs_WIRE)
|
||||
if (aW.ShapeType()!=TopAbs_WIRE) {
|
||||
continue;
|
||||
|
||||
}
|
||||
//
|
||||
myItW.Initialize(aW);
|
||||
for (; myItW.More(); myItW.Next())
|
||||
{
|
||||
for (; myItW.More(); myItW.Next()) {
|
||||
const TopoDS_Shape& aE=myItW.Value();
|
||||
if (theMEAvoid.Contains(aE))
|
||||
if (theMEAvoid.Contains(aE)){
|
||||
continue;
|
||||
|
||||
const BOPCol_ListOfShape& aLF = theMEF.FindFromKey(aE);
|
||||
BOPCol_ListIteratorOfListOfShape aItLF(aLF);
|
||||
for (; aItLF.More(); aItLF.Next())
|
||||
{
|
||||
const TopoDS_Shape& aFx = aItLF.Value();
|
||||
if (!aFx.IsSame(aF) && theMFDone.Add(aFx))
|
||||
theLCB.Append(aFx);
|
||||
}
|
||||
//
|
||||
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);
|
||||
}
|
||||
}
|
||||
//
|
||||
@@ -556,7 +616,7 @@ void BOPAlgo_Builder::FillIn3DParts
|
||||
BOPAlgo_VectorOfFillIn3DParts aVFIP;
|
||||
//
|
||||
for (i=0; i<aNbS; ++i) {
|
||||
BOPDS_ShapeInfo& aSI=myDS->ChangeShapeInfo(i);
|
||||
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType()!=TopAbs_SOLID) {
|
||||
continue;
|
||||
}
|
||||
@@ -576,9 +636,8 @@ void BOPAlgo_Builder::FillIn3DParts
|
||||
}
|
||||
//
|
||||
// 2.1 Bounding box for the solid aS [ aBoxS ]
|
||||
Bnd_Box& aBoxS = aSI.ChangeBox();
|
||||
if (aBoxS.IsVoid())
|
||||
myDS->BuildBndBoxSolid(i, aBoxS, myCheckInverted);
|
||||
Bnd_Box aBoxS;
|
||||
aBoxS=aSI.Box();
|
||||
//
|
||||
// 2.2 Build Draft Solid [aSD]
|
||||
BOPCol_ListOfShape aLIF;
|
||||
@@ -771,39 +830,32 @@ void BOPAlgo_Builder::BuildSplitSolids
|
||||
//
|
||||
} //for (i=1; i<=aNbS; ++i)
|
||||
//
|
||||
// Build temporary map of solids images to avoid rebuilding
|
||||
// of the solids without internal faces
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aSolidsIm;
|
||||
// 1. Build solids for interfered source solids
|
||||
// 1. Build solids for interferred source solids
|
||||
for (i=0; i<aNbS; ++i) {
|
||||
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
||||
if (aSI.ShapeType() != TopAbs_SOLID)
|
||||
continue;
|
||||
|
||||
const TopoDS_Shape& aS = aSI.Shape();
|
||||
const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
|
||||
if (!theDraftSolids.IsBound(aS))
|
||||
continue;
|
||||
|
||||
const TopoDS_Shape& aSD = theDraftSolids.Find(aS);
|
||||
const BOPCol_ListOfShape* pLFIN = theInParts.Seek(aS);
|
||||
if (!pLFIN)
|
||||
{
|
||||
aSolidsIm(aSolidsIm.Add(aS, BOPCol_ListOfShape())).Append(aSD);
|
||||
//
|
||||
if (aSI.ShapeType()!=TopAbs_SOLID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
aSFS.Clear();
|
||||
//
|
||||
const TopoDS_Shape& aS=aSI.Shape();
|
||||
const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
|
||||
if(!theDraftSolids.IsBound(aS)) {
|
||||
continue;
|
||||
}
|
||||
const TopoDS_Shape& aSD=theDraftSolids.Find(aS);
|
||||
const BOPCol_ListOfShape& aLFIN=
|
||||
(theInParts.IsBound(aS)) ? theInParts.Find(aS) : aLSEmpty;
|
||||
//
|
||||
// 1.1 Fill Shell Faces Set
|
||||
aSFS.Clear();
|
||||
aExp.Init(aSD, TopAbs_FACE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
const TopoDS_Shape& aF=aExp.Current();
|
||||
aSFS.Append(aF);
|
||||
}
|
||||
//
|
||||
// 1.2 Fill internal faces
|
||||
aIt.Initialize(*pLFIN);
|
||||
aIt.Initialize(aLFIN);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
TopoDS_Shape aF=aIt.Value();
|
||||
//
|
||||
@@ -829,18 +881,10 @@ void BOPAlgo_Builder::BuildSplitSolids
|
||||
BOPAlgo_BuilderSolidCnt::Perform(myRunParallel, aVBS);
|
||||
//===================================================
|
||||
//
|
||||
for (k = 0; k < aNbBS; ++k)
|
||||
{
|
||||
for (k=0; k<aNbBS; ++k) {
|
||||
BOPAlgo_BuilderSolid& aBS=aVBS(k);
|
||||
aSolidsIm.Add(aBS.Solid(), aBS.Areas());
|
||||
}
|
||||
//
|
||||
// Add new solids to images map
|
||||
aNbBS = aSolidsIm.Extent();
|
||||
for (k = 1; k <= aNbBS; ++k)
|
||||
{
|
||||
const TopoDS_Shape& aS = aSolidsIm.FindKey(k);
|
||||
const BOPCol_ListOfShape& aLSR = aSolidsIm(k);
|
||||
const TopoDS_Solid& aS=aBS.Solid();
|
||||
const BOPCol_ListOfShape& aLSR=aBS.Areas();
|
||||
//
|
||||
if (!myImages.IsBound(aS)) {
|
||||
BOPCol_ListOfShape* pLSx = myImages.Bound(aS, BOPCol_ListOfShape());
|
||||
|
@@ -50,8 +50,7 @@ BOPAlgo_Options::BOPAlgo_Options()
|
||||
myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
|
||||
myReport(new Message_Report),
|
||||
myRunParallel(myGlobalRunParallel),
|
||||
myFuzzyValue(Precision::Confusion()),
|
||||
myCheckInverted(Standard_True)
|
||||
myFuzzyValue(Precision::Confusion())
|
||||
{
|
||||
BOPAlgo_LoadMessages();
|
||||
}
|
||||
@@ -66,8 +65,7 @@ BOPAlgo_Options::BOPAlgo_Options
|
||||
myAllocator(theAllocator),
|
||||
myReport(new Message_Report),
|
||||
myRunParallel(myGlobalRunParallel),
|
||||
myFuzzyValue(Precision::Confusion()),
|
||||
myCheckInverted(Standard_True)
|
||||
myFuzzyValue(Precision::Confusion())
|
||||
{
|
||||
BOPAlgo_LoadMessages();
|
||||
}
|
||||
|
@@ -32,10 +32,6 @@ class Message_ProgressIndicator;
|
||||
//! touching or coinciding cases;
|
||||
//! - *Progress indicator* - provides interface to track the progress of
|
||||
//! operation and stop the operation by user's break.
|
||||
//! - *Disabling the check for inverted solids* - Disables/Enables the check of the input solids
|
||||
//! for inverted status (holes in the space). The default value is TRUE,
|
||||
//! i.e. the check is performed. Setting this flag to FALSE for inverted solids,
|
||||
//! most likely will lead to incorrect results.
|
||||
//!
|
||||
class BOPAlgo_Options
|
||||
{
|
||||
@@ -160,22 +156,6 @@ public:
|
||||
//! Set the Progress Indicator object.
|
||||
Standard_EXPORT void SetProgressIndicator(const Handle(Message_ProgressIndicator)& theObj);
|
||||
|
||||
public:
|
||||
//!@name Check input solids for inverted status
|
||||
|
||||
//! Enables/Disables the check of the input solids for inverted status
|
||||
void SetCheckInverted(const Standard_Boolean theCheck)
|
||||
{
|
||||
myCheckInverted = theCheck;
|
||||
}
|
||||
|
||||
//! Returns the flag defining whether the check for input solids on inverted status
|
||||
//! should be performed or not.
|
||||
Standard_Boolean CheckInverted() const
|
||||
{
|
||||
return myCheckInverted;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//! Breaks the execution if the break signal
|
||||
@@ -189,7 +169,6 @@ protected:
|
||||
Standard_Boolean myRunParallel;
|
||||
Standard_Real myFuzzyValue;
|
||||
Handle(Message_ProgressIndicator) myProgressIndicator;
|
||||
Standard_Boolean myCheckInverted;
|
||||
|
||||
};
|
||||
|
||||
|
@@ -207,41 +207,18 @@ void BOPAlgo_PaveFiller::PerformFF()
|
||||
//
|
||||
for (; myIterator->More(); myIterator->Next()) {
|
||||
myIterator->Value(nF1, nF2);
|
||||
|
||||
// Update/Initialize FaceInfo structure for first face
|
||||
if (myDS->HasFaceInfo(nF1))
|
||||
{
|
||||
if (aMIFence.Add(nF1))
|
||||
{
|
||||
//
|
||||
const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
|
||||
const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
|
||||
//
|
||||
if (aMIFence.Add(nF1)) {
|
||||
myDS->UpdateFaceInfoOn(nF1);
|
||||
myDS->UpdateFaceInfoIn(nF1);
|
||||
}
|
||||
}
|
||||
else if (myDS->HasInterfShapeSubShapes(nF2, nF1))
|
||||
{
|
||||
myDS->ChangeFaceInfo(nF1);
|
||||
aMIFence.Add(nF1);
|
||||
}
|
||||
|
||||
// Update/Initialize FaceInfo structure for second face
|
||||
if (myDS->HasFaceInfo(nF2))
|
||||
{
|
||||
if (aMIFence.Add(nF2))
|
||||
{
|
||||
if (aMIFence.Add(nF2)) {
|
||||
myDS->UpdateFaceInfoOn(nF2);
|
||||
myDS->UpdateFaceInfoIn(nF2);
|
||||
}
|
||||
}
|
||||
else if (myDS->HasInterfShapeSubShapes(nF1, nF2))
|
||||
{
|
||||
myDS->ChangeFaceInfo(nF2);
|
||||
aMIFence.Add(nF2);
|
||||
}
|
||||
//
|
||||
if (myGlue == BOPAlgo_GlueOff)
|
||||
{
|
||||
const TopoDS_Face& aF1 = (*(TopoDS_Face *)(&myDS->Shape(nF1)));
|
||||
const TopoDS_Face& aF2 = (*(TopoDS_Face *)(&myDS->Shape(nF2)));
|
||||
//
|
||||
const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(aF1);
|
||||
const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(aF2);
|
||||
@@ -257,6 +234,7 @@ void BOPAlgo_PaveFiller::PerformFF()
|
||||
}
|
||||
}
|
||||
//
|
||||
if (myGlue == BOPAlgo_GlueOff) {
|
||||
BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Append1();
|
||||
//
|
||||
aFaceFace.SetIndices(nF1, nF2);
|
||||
|
@@ -42,6 +42,12 @@ static
|
||||
void RefineShell(TopoDS_Shell& theShell,
|
||||
const BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
|
||||
BOPCol_ListOfShape& aLShX);
|
||||
//
|
||||
static
|
||||
void MapEdgesAndFaces
|
||||
(const TopoDS_Shape& aF,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator);
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPAlgo_CBK
|
||||
@@ -146,12 +152,162 @@ void BOPAlgo_ShellSplitter::Perform()
|
||||
{
|
||||
GetReport()->Clear();
|
||||
//
|
||||
BOPTools_AlgoTools::MakeConnexityBlocks
|
||||
(myStartShapes, TopAbs_EDGE, TopAbs_FACE, myLCB);
|
||||
MakeConnexityBlocks();
|
||||
if (HasErrors()) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
MakeShells();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MakeConnexityBlocks
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
|
||||
{
|
||||
Standard_Boolean bRegular;
|
||||
Standard_Integer i, j, aNbE, aNbES, aNbEP, k, aNbCB;
|
||||
TopoDS_Shape aFR;
|
||||
TopoDS_Iterator aItF, aItW;
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, myAllocator);
|
||||
BOPCol_IndexedMapOfShape aMEP(100, myAllocator);
|
||||
BOPCol_IndexedMapOfShape aMFC(100, myAllocator);
|
||||
BOPCol_MapOfShape aMER(100, myAllocator);
|
||||
BOPCol_MapOfShape aMFP(100, myAllocator);
|
||||
BOPCol_IndexedMapOfShape aMEAdd(100, myAllocator);
|
||||
BOPCol_MapOfShape aMES(100, myAllocator);
|
||||
BOPCol_ListIteratorOfListOfShape aIt;
|
||||
//
|
||||
myLCB.Clear();
|
||||
//
|
||||
const BOPCol_ListOfShape& aLSE=myStartShapes;
|
||||
aIt.Initialize(aLSE);
|
||||
for (i=1; aIt.More(); aIt.Next(), ++i) {
|
||||
const TopoDS_Shape& aSE=aIt.Value();
|
||||
if (!aMEP.Contains(aSE)) {
|
||||
aMEP.Add(aSE);
|
||||
MapEdgesAndFaces(aSE, aMEF, myAllocator);
|
||||
}
|
||||
else {
|
||||
aMER.Add(aSE);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 2
|
||||
aNbE=aMEF.Extent();
|
||||
for (i=1; i<=aNbE; ++i) {
|
||||
aNbES=aMES.Extent();
|
||||
if (aNbES==aNbE) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
const TopoDS_Shape& aE=aMEF.FindKey(i);
|
||||
//
|
||||
if (!aMES.Add(aE)) {
|
||||
continue;
|
||||
}
|
||||
// aMES - globally processed edges
|
||||
//
|
||||
//------------------------------------- goal: aMEC
|
||||
aMFC.Clear(); // aMEC - edges of CB
|
||||
aMEP.Clear(); // aMVP - edges to process right now
|
||||
aMEAdd.Clear(); // aMVAdd edges to process on next step of for(;;) {
|
||||
//
|
||||
aMEP.Add(aE);
|
||||
//
|
||||
for(;;) {
|
||||
aNbEP=aMEP.Extent();
|
||||
for (k=1; k<=aNbEP; ++k) {
|
||||
const TopoDS_Shape& aEP=aMEP(k);
|
||||
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aEP);
|
||||
aIt.Initialize(aLF);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aF=aIt.Value();
|
||||
if (aMFC.Add(aF)) {
|
||||
aItF.Initialize(aF);
|
||||
while (aItF.More()) {
|
||||
const TopoDS_Shape& aW=aItF.Value();
|
||||
if (aW.ShapeType()!=TopAbs_WIRE) {
|
||||
aItF.Next();
|
||||
continue;
|
||||
}
|
||||
//
|
||||
aItW.Initialize(aW);
|
||||
while (aItW.More()) {
|
||||
const TopoDS_Shape& aEF=aItW.Value();
|
||||
//
|
||||
if (aMES.Add(aEF)) {
|
||||
aMEAdd.Add(aEF);
|
||||
}
|
||||
//
|
||||
aItW.Next();
|
||||
}
|
||||
//
|
||||
aItF.Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
aNbEP=aMEAdd.Extent();
|
||||
if (!aNbEP) {
|
||||
break; // from for(;;) {
|
||||
}
|
||||
//
|
||||
aMEP.Clear();
|
||||
//
|
||||
for (k=1; k<=aNbEP; ++k) {
|
||||
const TopoDS_Shape& aEF=aMEAdd(k);
|
||||
aMEP.Add(aEF);
|
||||
}
|
||||
aMEAdd.Clear();
|
||||
}// for(;;) {
|
||||
//
|
||||
//-------------------------------------
|
||||
BOPTools_ConnexityBlock aCB(myAllocator);
|
||||
//
|
||||
BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMEFR(100, myAllocator);
|
||||
//
|
||||
bRegular=Standard_True;
|
||||
aNbCB = aMFC.Extent();
|
||||
for (j=1; j<=aNbCB; ++j) {
|
||||
aFR = aMFC(j);
|
||||
//
|
||||
if (aMER.Contains(aFR)) {
|
||||
aFR.Orientation(TopAbs_FORWARD);
|
||||
aLECB.Append(aFR);
|
||||
aFR.Orientation(TopAbs_REVERSED);
|
||||
aLECB.Append(aFR);
|
||||
bRegular=Standard_False;
|
||||
}
|
||||
else {
|
||||
aLECB.Append(aFR);
|
||||
}
|
||||
//
|
||||
if (bRegular) {
|
||||
MapEdgesAndFaces(aFR, aMEFR, myAllocator);
|
||||
}
|
||||
}
|
||||
//
|
||||
if (bRegular) {
|
||||
Standard_Integer aNbER, aNbFR;
|
||||
//
|
||||
aNbER=aMEFR.Extent();
|
||||
for (k=1; k<=aNbER; ++k) {
|
||||
const BOPCol_ListOfShape& aLFR=aMEFR(k);
|
||||
aNbFR=aLFR.Extent();
|
||||
if (aNbFR>2) {
|
||||
bRegular=!bRegular;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
aCB.SetRegular(bRegular);
|
||||
myLCB.Append(aCB);
|
||||
}
|
||||
}
|
||||
//=======================================================================
|
||||
//function : SplitBlock
|
||||
//purpose :
|
||||
@@ -594,3 +750,43 @@ void MakeShell(const BOPCol_ListOfShape& aLS,
|
||||
//
|
||||
BOPTools_AlgoTools::OrientFacesOnShell(aShell);
|
||||
}
|
||||
//=======================================================================
|
||||
// function: MapEdgesAndFaces
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void MapEdgesAndFaces
|
||||
(const TopoDS_Shape& aF,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
{
|
||||
TopoDS_Iterator aItF, aItW;
|
||||
//
|
||||
aItF.Initialize(aF);
|
||||
while (aItF.More()) {
|
||||
const TopoDS_Shape& aW=aItF.Value();
|
||||
if (aW.ShapeType()!=TopAbs_WIRE) {
|
||||
aItF.Next();
|
||||
continue;
|
||||
}
|
||||
//
|
||||
aItW.Initialize(aW);
|
||||
while (aItW.More()) {
|
||||
const TopoDS_Shape& aE=aItW.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);
|
||||
}
|
||||
//
|
||||
aItW.Next();
|
||||
}
|
||||
//
|
||||
aItF.Next();
|
||||
}
|
||||
}
|
||||
|
@@ -61,6 +61,8 @@ Standard_EXPORT virtual ~BOPAlgo_ShellSplitter();
|
||||
|
||||
protected:
|
||||
|
||||
Standard_EXPORT void MakeConnexityBlocks();
|
||||
|
||||
Standard_EXPORT void MakeShells();
|
||||
|
||||
|
||||
|
@@ -24,7 +24,6 @@
|
||||
#include <BOPCol_NCVector.hxx>
|
||||
#include <BOPCol_Parallel.hxx>
|
||||
#include <BOPTools.hxx>
|
||||
#include <BOPTools_AlgoTools.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
@@ -125,12 +124,153 @@ void BOPAlgo_WireSplitter::Perform()
|
||||
myContext = new IntTools_Context;
|
||||
}
|
||||
//
|
||||
BOPTools_AlgoTools::MakeConnexityBlocks
|
||||
(myWES->StartElements(), TopAbs_VERTEX, TopAbs_EDGE, myLCB);
|
||||
|
||||
MakeConnexityBlocks();
|
||||
MakeWires();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MakeConnexityBlocks
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPAlgo_WireSplitter::MakeConnexityBlocks()
|
||||
{
|
||||
Standard_Boolean bRegular, bClosed;
|
||||
Standard_Integer i, j, aNbV, aNbVS, aNbVP, k;
|
||||
TopoDS_Iterator aItE;
|
||||
TopoDS_Shape aER;
|
||||
BOPCol_ListIteratorOfListOfShape aIt;
|
||||
//
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMVE(100, myAllocator);
|
||||
BOPCol_IndexedMapOfShape aMVP(100, myAllocator);
|
||||
BOPCol_IndexedMapOfShape aMEC(100, myAllocator);
|
||||
BOPCol_MapOfShape aMER(100, myAllocator);
|
||||
BOPCol_MapOfShape aMEP(100, myAllocator);
|
||||
BOPCol_IndexedMapOfShape aMVAdd(100, myAllocator);
|
||||
BOPCol_MapOfShape aMVS(100, myAllocator);
|
||||
//
|
||||
myLCB.Clear();
|
||||
//
|
||||
const BOPCol_ListOfShape& aLSE=myWES->StartElements();
|
||||
aIt.Initialize(aLSE);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aE=aIt.Value();
|
||||
if (aMEP.Add(aE)) {
|
||||
BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
|
||||
}
|
||||
else {
|
||||
aMER.Add(aE);
|
||||
}
|
||||
}
|
||||
//
|
||||
// 2
|
||||
aNbV=aMVE.Extent();
|
||||
for (i=1; i<=aNbV; ++i) {
|
||||
aNbVS=aMVS.Extent();
|
||||
if (aNbVS==aNbV) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
const TopoDS_Shape& aV=aMVE.FindKey(i);
|
||||
//
|
||||
if (!aMVS.Add(aV)) {
|
||||
continue;
|
||||
}
|
||||
// aMVS - globally processed vertices
|
||||
//
|
||||
//------------------------------------- goal: aMEC
|
||||
aMEC.Clear(); // aMEC - edges of CB
|
||||
aMVP.Clear(); // aMVP - vertices to process right now
|
||||
aMVAdd.Clear(); // aMVAdd vertices to process on next step of while(1)
|
||||
//
|
||||
aMVP.Add(aV);
|
||||
//
|
||||
for(;;) {
|
||||
aNbVP=aMVP.Extent();
|
||||
for (k=1; k<=aNbVP; ++k) {
|
||||
const TopoDS_Shape& aVP=aMVP(k);
|
||||
const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aVP);
|
||||
aIt.Initialize(aLE);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Shape& aE=aIt.Value();
|
||||
if (aMEC.Add(aE)) {
|
||||
aItE.Initialize(aE);
|
||||
for (; aItE.More(); aItE.Next()) {
|
||||
const TopoDS_Shape& aVE=aItE.Value();
|
||||
if (aMVS.Add(aVE)) {
|
||||
aMVAdd.Add(aVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}//for (k=1; k<=aNbVP; ++k) {
|
||||
//
|
||||
aNbVP=aMVAdd.Extent();
|
||||
if (!aNbVP) {
|
||||
break; // from while(1)
|
||||
}
|
||||
//
|
||||
aMVP.Clear();
|
||||
//
|
||||
for (k=1; k<=aNbVP; ++k) {
|
||||
const TopoDS_Shape& aVE=aMVAdd(k);
|
||||
aMVP.Add(aVE);
|
||||
}
|
||||
aMVAdd.Clear();
|
||||
}// while(1) {
|
||||
|
||||
//-------------------------------------
|
||||
BOPTools_ConnexityBlock aCB(myAllocator);
|
||||
BOPCol_ListOfShape& aLEC=aCB.ChangeShapes();
|
||||
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aMVER(100, myAllocator);
|
||||
//
|
||||
bRegular=Standard_True;
|
||||
Standard_Integer aNbCB = aMEC.Extent();
|
||||
for (j = 1; j <= aNbCB; j++) {
|
||||
aER = aMEC(j);
|
||||
//
|
||||
if (aMER.Contains(aER)) {
|
||||
aER.Orientation(TopAbs_FORWARD);
|
||||
aLEC.Append(aER);
|
||||
aER.Orientation(TopAbs_REVERSED);
|
||||
aLEC.Append(aER);
|
||||
bRegular=Standard_False;
|
||||
}
|
||||
else {
|
||||
aLEC.Append(aER);
|
||||
}
|
||||
//
|
||||
if (bRegular) {
|
||||
BOPTools::MapShapesAndAncestors(aER, TopAbs_VERTEX, TopAbs_EDGE, aMVER);
|
||||
}
|
||||
}
|
||||
//
|
||||
if (bRegular) {
|
||||
Standard_Integer aNbVR, aNbER;
|
||||
//
|
||||
aNbVR=aMVER.Extent();
|
||||
for (k=1; k<=aNbVR; ++k) {
|
||||
const BOPCol_ListOfShape& aLER=aMVER(k);
|
||||
aNbER=aLER.Extent();
|
||||
if (aNbER==1) {
|
||||
const TopoDS_Edge& aEx=TopoDS::Edge(aER);
|
||||
bClosed=BRep_Tool::IsClosed(aEx, myWES->Face());
|
||||
if (!bClosed) {
|
||||
bRegular=!bRegular;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (aNbER>2) {
|
||||
bRegular=!bRegular;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
aCB.SetRegular(bRegular);
|
||||
myLCB.Append(aCB);
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
class BOPAlgo_WS_ConnexityBlock {
|
||||
public:
|
||||
|
@@ -70,6 +70,8 @@ protected:
|
||||
|
||||
Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT void MakeConnexityBlocks();
|
||||
|
||||
Standard_EXPORT void MakeWires();
|
||||
|
||||
BOPAlgo_PWireEdgeSet myWES;
|
||||
|
@@ -545,11 +545,6 @@ void BOPDS_DS::Init(const Standard_Real theFuzz)
|
||||
}//if (aTS==TopAbs_FACE) {
|
||||
}//for (j=0; j<myNbSourceShapes; ++j) {
|
||||
//
|
||||
// For the check mode we need to compute the bounding box for solid.
|
||||
// Otherwise, it will be computed on the building stage
|
||||
Standard_Boolean bCheckMode = (myArguments.Extent() == 1);
|
||||
if (bCheckMode)
|
||||
{
|
||||
// 2.4 Solids
|
||||
for (j=0; j<myNbSourceShapes; ++j) {
|
||||
BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
|
||||
@@ -602,7 +597,6 @@ void BOPDS_DS::Init(const Standard_Real theFuzz)
|
||||
}
|
||||
aMI.Clear();
|
||||
}//for (j=0; j<myNbSourceShapes; ++j) {
|
||||
}
|
||||
//
|
||||
aMI.Clear();
|
||||
//-----------------------------------------------------
|
||||
@@ -1872,8 +1866,7 @@ Standard_Real ComputeParameter(const TopoDS_Vertex& aV,
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPDS_DS::BuildBndBoxSolid(const Standard_Integer theIndex,
|
||||
Bnd_Box& aBoxS,
|
||||
const Standard_Boolean theCheckInverted)
|
||||
Bnd_Box& aBoxS)
|
||||
{
|
||||
Standard_Boolean bIsOpenBox, bIsInverted;
|
||||
Standard_Integer nSh, nFc;
|
||||
@@ -1937,7 +1930,7 @@ void BOPDS_DS::BuildBndBoxSolid(const Standard_Integer theIndex,
|
||||
if (bIsOpenBox) {
|
||||
aBoxS.SetWhole();
|
||||
}
|
||||
else if (theCheckInverted) {
|
||||
else {
|
||||
bIsInverted=BOPTools_AlgoTools::IsInvertedSolid(aSolid);
|
||||
if (bIsInverted) {
|
||||
aBoxS.SetWhole();
|
||||
|
@@ -468,13 +468,6 @@ Standard_EXPORT virtual ~BOPDS_DS();
|
||||
//! of the existing vertices have been increased.
|
||||
Standard_EXPORT Standard_Boolean IsValidShrunkData(const Handle(BOPDS_PaveBlock)& thePB);
|
||||
|
||||
//! Computes bounding box <theBox> for the solid with DS-index <theIndex>.
|
||||
//! The flag <theCheckInverted> enables/disables the check of the solid
|
||||
//! for inverted status. By default the solids will be checked.
|
||||
Standard_EXPORT void BuildBndBoxSolid (const Standard_Integer theIndex,
|
||||
Bnd_Box& theBox,
|
||||
const Standard_Boolean theCheckInverted = Standard_True);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -492,6 +485,10 @@ protected:
|
||||
const Standard_Real theFuzz);
|
||||
|
||||
|
||||
//! Computes bouding box <theBox> for the solid with DS-index <theIndex>
|
||||
Standard_EXPORT void BuildBndBoxSolid (const Standard_Integer theIndex, Bnd_Box& theBox);
|
||||
|
||||
|
||||
BOPCol_BaseAllocator myAllocator;
|
||||
BOPCol_ListOfShape myArguments;
|
||||
Standard_Integer myNbShapes;
|
||||
|
@@ -133,7 +133,6 @@ Standard_Integer bapibop(Draw_Interpretor& di,
|
||||
pBuilder->SetFuzzyValue(aFuzzyValue);
|
||||
pBuilder->SetNonDestructive(bNonDestructive);
|
||||
pBuilder->SetGlue(aGlue);
|
||||
pBuilder->SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
pBuilder->Build();
|
||||
//
|
||||
@@ -194,7 +193,6 @@ Standard_Integer bapibuild(Draw_Interpretor& di,
|
||||
aBuilder.SetFuzzyValue(aFuzzyValue);
|
||||
aBuilder.SetNonDestructive(bNonDestructive);
|
||||
aBuilder.SetGlue(aGlue);
|
||||
aBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
aBuilder.Build();
|
||||
//
|
||||
@@ -259,7 +257,6 @@ Standard_Integer bapisplit(Draw_Interpretor& di,
|
||||
aSplitter.SetFuzzyValue(BOPTest_Objects::FuzzyValue());
|
||||
aSplitter.SetNonDestructive(BOPTest_Objects::NonDestructive());
|
||||
aSplitter.SetGlue(BOPTest_Objects::Glue());
|
||||
aSplitter.SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
// performing operation
|
||||
aSplitter.Build();
|
||||
|
@@ -250,7 +250,6 @@ Standard_Integer bopsmt(Draw_Interpretor& di,
|
||||
aBOP.AddTool(aS2);
|
||||
aBOP.SetOperation(aOp);
|
||||
aBOP.SetRunParallel (bRunParallel);
|
||||
aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
aBOP.PerformWithFiller(*pPF);
|
||||
BOPTest::ReportAlerts(aBOP);
|
||||
@@ -311,7 +310,6 @@ Standard_Integer bopsection(Draw_Interpretor& di,
|
||||
aBOP.AddArgument(aS1);
|
||||
aBOP.AddArgument(aS2);
|
||||
aBOP.SetRunParallel (bRunParallel);
|
||||
aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
aBOP.PerformWithFiller(*pPF);
|
||||
BOPTest::ReportAlerts(aBOP);
|
||||
@@ -510,7 +508,6 @@ Standard_Integer bsmt (Draw_Interpretor& di,
|
||||
aBOP.AddTool(aS2);
|
||||
aBOP.SetOperation(aOp);
|
||||
aBOP.SetRunParallel(bRunParallel);
|
||||
aBOP.SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
aBOP.PerformWithFiller(aPF);
|
||||
BOPTest::ReportAlerts(aBOP);
|
||||
|
@@ -111,7 +111,6 @@ Standard_Integer bcbuild(Draw_Interpretor& di,
|
||||
aCBuilder.SetFuzzyValue(aTol);
|
||||
aCBuilder.SetNonDestructive(bNonDestructive);
|
||||
aCBuilder.SetGlue(aGlue);
|
||||
aCBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
aCBuilder.PerformWithFiller(aPF);
|
||||
BOPTest::ReportAlerts(aCBuilder);
|
||||
|
@@ -55,7 +55,6 @@ class BOPTest_Session {
|
||||
myFuzzyValue = 0.;
|
||||
myGlue = BOPAlgo_GlueOff;
|
||||
myDrawWarnShapes = Standard_False;
|
||||
myCheckInverted = Standard_True;
|
||||
};
|
||||
//
|
||||
// Clear
|
||||
@@ -143,14 +142,6 @@ class BOPTest_Session {
|
||||
return myDrawWarnShapes;
|
||||
};
|
||||
//
|
||||
void SetCheckInverted(const Standard_Boolean bCheck) {
|
||||
myCheckInverted = bCheck;
|
||||
};
|
||||
//
|
||||
Standard_Boolean CheckInverted() const {
|
||||
return myCheckInverted;
|
||||
};
|
||||
//
|
||||
protected:
|
||||
//
|
||||
BOPTest_Session(const BOPTest_Session&);
|
||||
@@ -169,7 +160,6 @@ protected:
|
||||
Standard_Real myFuzzyValue;
|
||||
BOPAlgo_GlueEnum myGlue;
|
||||
Standard_Boolean myDrawWarnShapes;
|
||||
Standard_Boolean myCheckInverted;
|
||||
};
|
||||
//
|
||||
//=======================================================================
|
||||
@@ -380,22 +370,6 @@ Standard_Boolean BOPTest_Objects::DrawWarnShapes()
|
||||
return GetSession().DrawWarnShapes();
|
||||
}
|
||||
//=======================================================================
|
||||
//function : SetCheckInverted
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BOPTest_Objects::SetCheckInverted(const Standard_Boolean bCheck)
|
||||
{
|
||||
GetSession().SetCheckInverted(bCheck);
|
||||
}
|
||||
//=======================================================================
|
||||
//function : CheckInverted
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BOPTest_Objects::CheckInverted()
|
||||
{
|
||||
return GetSession().CheckInverted();
|
||||
}
|
||||
//=======================================================================
|
||||
//function : Allocator1
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
@@ -87,10 +87,6 @@ public:
|
||||
|
||||
Standard_EXPORT static Standard_Boolean DrawWarnShapes();
|
||||
|
||||
Standard_EXPORT static void SetCheckInverted(const Standard_Boolean bCheck);
|
||||
|
||||
Standard_EXPORT static Standard_Boolean CheckInverted();
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
@@ -27,7 +27,6 @@ static Standard_Integer bnondestructive(Draw_Interpretor&, Standard_Integer, con
|
||||
static Standard_Integer bfuzzyvalue(Draw_Interpretor&, Standard_Integer, const char**);
|
||||
static Standard_Integer bGlue(Draw_Interpretor&, Standard_Integer, const char**);
|
||||
static Standard_Integer bdrawwarnshapes(Draw_Interpretor&, Standard_Integer, const char**);
|
||||
static Standard_Integer bcheckinverted(Draw_Interpretor&, Standard_Integer, const char**);
|
||||
|
||||
//=======================================================================
|
||||
//function : OptionCommands
|
||||
@@ -49,8 +48,6 @@ void BOPTest::OptionCommands(Draw_Interpretor& theCommands)
|
||||
theCommands.Add("bdrawwarnshapes", "Defines whether to draw warning shapes or not\n"
|
||||
"Usage: bdrawwarnshapes [0 (do not draw) / 1 (draw warning shapes)",
|
||||
__FILE__, bdrawwarnshapes, g);
|
||||
theCommands.Add("bcheckinverted", "Defines whether to check the input solids on inverted status or not\n"
|
||||
"Usage: bcheckinverted [0 (off) / 1 (on)]", __FILE__, bcheckinverted, g);
|
||||
}
|
||||
//=======================================================================
|
||||
//function : boptions
|
||||
@@ -75,7 +72,6 @@ Standard_Integer boptions(Draw_Interpretor& di,
|
||||
aFuzzyValue = BOPTest_Objects::FuzzyValue();
|
||||
aGlue = BOPTest_Objects::Glue();
|
||||
Standard_Boolean bDrawWarnShapes = BOPTest_Objects::DrawWarnShapes();
|
||||
Standard_Boolean bCheckInverted = BOPTest_Objects::CheckInverted();
|
||||
//
|
||||
Sprintf(buf, " RunParallel: %d\n", bRunParallel);
|
||||
di << buf;
|
||||
@@ -88,8 +84,6 @@ Standard_Integer boptions(Draw_Interpretor& di,
|
||||
di << buf;
|
||||
Sprintf(buf, " Draw Warning Shapes: %s\n", bDrawWarnShapes ? "Yes" : "No");
|
||||
di << buf;
|
||||
Sprintf(buf, " Check for inverted solids: %s\n", bCheckInverted ? "Yes" : "No");
|
||||
di << buf;
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
@@ -215,21 +209,3 @@ Standard_Integer bdrawwarnshapes(Draw_Interpretor& di,
|
||||
BOPTest_Objects::SetDrawWarnShapes(iDraw != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : bcheckinverted
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer bcheckinverted(Draw_Interpretor& di,
|
||||
Standard_Integer n,
|
||||
const char** a)
|
||||
{
|
||||
if (n != 2) {
|
||||
di.PrintHelp(a[0]);
|
||||
return 1;
|
||||
}
|
||||
//
|
||||
Standard_Integer iCheck = Draw::Atoi(a[1]);
|
||||
BOPTest_Objects::SetCheckInverted(iCheck != 0);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -188,7 +188,6 @@ Standard_Integer bbuild(Draw_Interpretor& di,
|
||||
}
|
||||
}
|
||||
aBuilder.SetRunParallel(bRunParallel);
|
||||
aBuilder.SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
//
|
||||
OSD_Timer aTimer;
|
||||
@@ -299,7 +298,6 @@ Standard_Integer bbop(Draw_Interpretor& di,
|
||||
}
|
||||
//
|
||||
pBuilder->SetRunParallel(bRunParallel);
|
||||
pBuilder->SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
OSD_Timer aTimer;
|
||||
aTimer.Start();
|
||||
@@ -365,7 +363,6 @@ Standard_Integer bsplit(Draw_Interpretor& di,
|
||||
pSplitter->SetRunParallel(BOPTest_Objects::RunParallel());
|
||||
pSplitter->SetNonDestructive(BOPTest_Objects::NonDestructive());
|
||||
pSplitter->SetFuzzyValue(BOPTest_Objects::FuzzyValue());
|
||||
pSplitter->SetCheckInverted(BOPTest_Objects::CheckInverted());
|
||||
//
|
||||
// measure the time of the operation
|
||||
OSD_Timer aTimer;
|
||||
|
@@ -71,28 +71,38 @@ void BOPTools::MapShapesAndAncestors
|
||||
(const TopoDS_Shape& S,
|
||||
const TopAbs_ShapeEnum TS,
|
||||
const TopAbs_ShapeEnum TA,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& Map)
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& aMEF)
|
||||
{
|
||||
// visit ancestors
|
||||
TopExp_Explorer aExA(S, TA);
|
||||
for (; aExA.More(); aExA.Next())
|
||||
{
|
||||
// visit shapes
|
||||
const TopoDS_Shape& anAnc = aExA.Current();
|
||||
TopExp_Explorer aExS, aExA;
|
||||
//
|
||||
TopExp_Explorer aExS(anAnc, TS);
|
||||
for (; aExS.More(); aExS.Next())
|
||||
{
|
||||
const TopoDS_Shape& aSS = aExS.Current();
|
||||
BOPCol_ListOfShape* pLA = Map.ChangeSeek(aSS);
|
||||
if (!pLA)
|
||||
pLA = &Map(Map.Add(aSS, BOPCol_ListOfShape()));
|
||||
pLA->Append(anAnc);
|
||||
// visit ancestors
|
||||
aExA.Init(S, TA);
|
||||
while (aExA.More()) {
|
||||
// visit shapes
|
||||
const TopoDS_Shape& aF = aExA.Current();
|
||||
//
|
||||
aExS.Init(aF, TS);
|
||||
while (aExS.More()) {
|
||||
const TopoDS_Shape& aE= aExS.Current();
|
||||
if (aMEF.Contains(aE)) {
|
||||
aMEF.ChangeFromKey(aE).Append(aF);
|
||||
}
|
||||
else {
|
||||
BOPCol_ListOfShape aLS;
|
||||
aLS.Append(aF);
|
||||
aMEF.Add(aE, aLS);
|
||||
}
|
||||
|
||||
aExS.Next();
|
||||
}
|
||||
aExA.Next();
|
||||
}
|
||||
//
|
||||
// visit shapes not under ancestors
|
||||
TopExp_Explorer aExS(S, TS, TA);
|
||||
for (; aExS.More(); aExS.Next())
|
||||
Map.Add(aExS.Current(), BOPCol_ListOfShape());
|
||||
aExS.Init(S, TS, TA);
|
||||
while (aExS.More()) {
|
||||
const TopoDS_Shape& aE=aExS.Current();
|
||||
BOPCol_ListOfShape aLS;
|
||||
aMEF.Add(aE, aLS);
|
||||
aExS.Next();
|
||||
}
|
||||
}
|
||||
|
@@ -120,149 +120,52 @@ static
|
||||
//=======================================================================
|
||||
void BOPTools_AlgoTools::MakeConnexityBlocks
|
||||
(const TopoDS_Shape& theS,
|
||||
const TopAbs_ShapeEnum theConnectionType,
|
||||
const TopAbs_ShapeEnum theElementType,
|
||||
BOPCol_ListOfListOfShape& theLCB,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theConnectionMap)
|
||||
const TopAbs_ShapeEnum theType1,
|
||||
const TopAbs_ShapeEnum theType2,
|
||||
BOPCol_ListOfShape& theLCB)
|
||||
{
|
||||
// Map shapes to find connected elements
|
||||
BOPTools::MapShapesAndAncestors(theS, theConnectionType, theElementType, theConnectionMap);
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aDMSLS;
|
||||
BOPTools::MapShapesAndAncestors(theS, theType1, theType2, aDMSLS);
|
||||
// Fence map
|
||||
BOPCol_MapOfShape aMFence;
|
||||
|
||||
TopExp_Explorer aExp(theS, theElementType);
|
||||
for (; aExp.More(); aExp.Next())
|
||||
{
|
||||
Standard_Integer i;
|
||||
BRep_Builder aBB;
|
||||
//
|
||||
TopExp_Explorer aExp(theS, theType2);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
const TopoDS_Shape& aS = aExp.Current();
|
||||
if (!aMFence.Add(aS)) {
|
||||
continue;
|
||||
}
|
||||
// The block
|
||||
BOPCol_ListOfShape aLBlock;
|
||||
BOPCol_IndexedMapOfShape aMBlock;
|
||||
TopoDS_Compound aBlock;
|
||||
aBB.MakeCompound(aBlock);
|
||||
// Start the block
|
||||
aLBlock.Append(aS);
|
||||
aMBlock.Add(aS);
|
||||
aBB.Add(aBlock, aS);
|
||||
// Look for connected parts
|
||||
BOPCol_ListIteratorOfListOfShape aItB(aLBlock);
|
||||
for (; aItB.More(); aItB.Next())
|
||||
{
|
||||
const TopoDS_Shape& aS1 = aItB.Value();
|
||||
TopExp_Explorer aExpSS(aS1, theConnectionType);
|
||||
for (; aExpSS.More(); aExpSS.Next())
|
||||
{
|
||||
for (i = 1; i <= aMBlock.Extent(); ++i) {
|
||||
const TopoDS_Shape& aS1 = aMBlock(i);
|
||||
TopExp_Explorer aExpSS(aS1, theType1);
|
||||
for (; aExpSS.More(); aExpSS.Next()) {
|
||||
const TopoDS_Shape& aSubS = aExpSS.Current();
|
||||
const BOPCol_ListOfShape& aLS = theConnectionMap.FindFromKey(aSubS);
|
||||
const BOPCol_ListOfShape& aLS = aDMSLS.FindFromKey(aSubS);
|
||||
BOPCol_ListIteratorOfListOfShape aItLS(aLS);
|
||||
for (; aItLS.More(); aItLS.Next())
|
||||
{
|
||||
for (; aItLS.More(); aItLS.Next()) {
|
||||
const TopoDS_Shape& aS2 = aItLS.Value();
|
||||
if (aMFence.Add(aS2))
|
||||
aLBlock.Append(aS2);
|
||||
if (aMFence.Add(aS2)) {
|
||||
aMBlock.Add(aS2);
|
||||
aBB.Add(aBlock, aS2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add the block into result
|
||||
theLCB.Append(aLBlock);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function: MakeConnexityBlocks
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPTools_AlgoTools::MakeConnexityBlocks
|
||||
(const TopoDS_Shape& theS,
|
||||
const TopAbs_ShapeEnum theConnectionType,
|
||||
const TopAbs_ShapeEnum theElementType,
|
||||
BOPCol_ListOfShape& theLCB)
|
||||
{
|
||||
BOPCol_ListOfListOfShape aLBlocks;
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aCMap;
|
||||
BOPTools_AlgoTools::MakeConnexityBlocks(theS, theConnectionType, theElementType, aLBlocks, aCMap);
|
||||
|
||||
// Make compound from each block
|
||||
BOPCol_ListIteratorOfListOfListOfShape aItB(aLBlocks);
|
||||
for (; aItB.More(); aItB.Next())
|
||||
{
|
||||
const BOPCol_ListOfShape& aLB = aItB.Value();
|
||||
|
||||
TopoDS_Compound aBlock;
|
||||
BRep_Builder().MakeCompound(aBlock);
|
||||
for (BOPCol_ListIteratorOfListOfShape it(aLB); it.More(); it.Next())
|
||||
BRep_Builder().Add(aBlock, it.Value());
|
||||
|
||||
theLCB.Append(aBlock);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function: MakeConnexityBlocks
|
||||
// purpose:
|
||||
//=======================================================================
|
||||
void BOPTools_AlgoTools::MakeConnexityBlocks
|
||||
(const BOPCol_ListOfShape& theLS,
|
||||
const TopAbs_ShapeEnum theConnectionType,
|
||||
const TopAbs_ShapeEnum theElementType,
|
||||
BOPTools_ListOfConnexityBlock& theLCB)
|
||||
{
|
||||
BRep_Builder aBB;
|
||||
// Make connexity blocks from start elements
|
||||
TopoDS_Compound aCStart;
|
||||
aBB.MakeCompound(aCStart);
|
||||
|
||||
BOPCol_MapOfShape aMFence, aMNRegular;
|
||||
|
||||
BOPCol_ListIteratorOfListOfShape aItL(theLS);
|
||||
for (; aItL.More(); aItL.Next())
|
||||
{
|
||||
const TopoDS_Shape& aS = aItL.Value();
|
||||
if (aMFence.Add(aS))
|
||||
aBB.Add(aCStart, aS);
|
||||
else
|
||||
aMNRegular.Add(aS);
|
||||
}
|
||||
|
||||
BOPCol_ListOfListOfShape aLCB;
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape aCMap;
|
||||
BOPTools_AlgoTools::MakeConnexityBlocks(aCStart, theConnectionType, theElementType, aLCB, aCMap);
|
||||
|
||||
// Save the blocks and check their regularity
|
||||
BOPCol_ListIteratorOfListOfListOfShape aItB(aLCB);
|
||||
for (; aItB.More(); aItB.Next())
|
||||
{
|
||||
const BOPCol_ListOfShape& aBlock = aItB.Value();
|
||||
|
||||
BOPTools_ConnexityBlock aCB;
|
||||
BOPCol_ListOfShape& aLCS = aCB.ChangeShapes();
|
||||
|
||||
Standard_Boolean bRegular = Standard_True;
|
||||
for (BOPCol_ListIteratorOfListOfShape it(aBlock); it.More(); it.Next())
|
||||
{
|
||||
TopoDS_Shape aS = it.Value();
|
||||
if (aMNRegular.Contains(aS))
|
||||
{
|
||||
bRegular = Standard_False;
|
||||
aS.Orientation(TopAbs_FORWARD);
|
||||
aLCS.Append(aS);
|
||||
aS.Orientation(TopAbs_REVERSED);
|
||||
aLCS.Append(aS);
|
||||
}
|
||||
else
|
||||
{
|
||||
aLCS.Append(aS);
|
||||
if (bRegular)
|
||||
{
|
||||
// Check if there are no multi-connected shapes
|
||||
for (TopExp_Explorer ex(aS, theConnectionType); ex.More() && bRegular; ex.Next())
|
||||
bRegular = (aCMap.FindFromKey(ex.Current()).Extent() == 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aCB.SetRegular(bRegular);
|
||||
theLCB.Append(aCB);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// function: OrientEdgesOnWire
|
||||
// purpose: Reorient edges on wire for correct ordering
|
||||
|
@@ -28,9 +28,7 @@
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <TopAbs_ShapeEnum.hxx>
|
||||
#include <BOPTools_ListOfCoupleOfShape.hxx>
|
||||
#include <BOPTools_ListOfConnexityBlock.hxx>
|
||||
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <BOPCol_ListOfListOfShape.hxx>
|
||||
#include <TopAbs_State.hxx>
|
||||
#include <BOPCol_IndexedMapOfShape.hxx>
|
||||
#include <BOPCol_BaseAllocator.hxx>
|
||||
@@ -191,33 +189,10 @@ public:
|
||||
//! the treatment
|
||||
Standard_EXPORT static void MakeConnexityBlock (BOPCol_ListOfShape& theLS, BOPCol_IndexedMapOfShape& theMapAvoid, BOPCol_ListOfShape& theLSCB, const BOPCol_BaseAllocator& theAllocator);
|
||||
|
||||
//! For the compound <theS> builds the blocks (compounds) of
|
||||
//! elements of type <theElementType> connected through the shapes
|
||||
//! of the type <theConnectionType>.
|
||||
//! The blocks are stored into the list <theLCB>.
|
||||
Standard_EXPORT static void MakeConnexityBlocks(const TopoDS_Shape& theS,
|
||||
const TopAbs_ShapeEnum theConnectionType,
|
||||
const TopAbs_ShapeEnum theElementType,
|
||||
BOPCol_ListOfShape& theLCB);
|
||||
|
||||
//! For the compound <theS> builds the blocks (compounds) of
|
||||
//! elements of type <theElementType> connected through the shapes
|
||||
//! of the type <theConnectionType>.
|
||||
//! The blocks are stored into the list of lists <theLCB>.
|
||||
//! Returns also the connection map <theConnectionMap>, filled during operation.
|
||||
Standard_EXPORT static void MakeConnexityBlocks(const TopoDS_Shape& theS,
|
||||
const TopAbs_ShapeEnum theConnectionType,
|
||||
const TopAbs_ShapeEnum theElementType,
|
||||
BOPCol_ListOfListOfShape& theLCB,
|
||||
BOPCol_IndexedDataMapOfShapeListOfShape& theConnectionMap);
|
||||
|
||||
//! Makes connexity blocks of elements of the given type with the given type of the
|
||||
//! connecting elements. The blocks are checked on regularity (multi-connectivity)
|
||||
//! and stored to the list of blocks <theLCB>.
|
||||
Standard_EXPORT static void MakeConnexityBlocks(const BOPCol_ListOfShape& theLS,
|
||||
const TopAbs_ShapeEnum theConnectionType,
|
||||
const TopAbs_ShapeEnum theElementType,
|
||||
BOPTools_ListOfConnexityBlock& theLCB);
|
||||
//! For the compound theS build the blocks
|
||||
//! theLCB (as list of compounds)
|
||||
//! in terms of connexity by the shapes of theType
|
||||
Standard_EXPORT static void MakeConnexityBlocks (const TopoDS_Shape& theS, const TopAbs_ShapeEnum theType1, const TopAbs_ShapeEnum theType2, BOPCol_ListOfShape& theLCB);
|
||||
|
||||
//! Correctly orients edges on the wire
|
||||
Standard_EXPORT static void OrientEdgesOnWire (TopoDS_Shape& theWire);
|
||||
|
@@ -66,6 +66,9 @@
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
|
||||
static
|
||||
Standard_Boolean CheckEdgeLength (const TopoDS_Edge& );
|
||||
|
||||
static
|
||||
Handle(Geom2d_Curve) BRep_Tool_CurveOnSurface(const TopoDS_Edge& ,
|
||||
const TopoDS_Face& ,
|
||||
@@ -129,6 +132,9 @@ Standard_Boolean BOPTools_AlgoTools2D::EdgeTangent
|
||||
if (isdgE) {
|
||||
return Standard_False;
|
||||
}
|
||||
if (!CheckEdgeLength(anEdge)) {
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
Handle(Geom_Curve) aC=BRep_Tool::Curve(anEdge, first, last);
|
||||
gp_Pnt aP;
|
||||
@@ -703,6 +709,44 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : CheckEdgeLength
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean CheckEdgeLength (const TopoDS_Edge& E)
|
||||
{
|
||||
BRepAdaptor_Curve BC(E);
|
||||
|
||||
BOPCol_IndexedMapOfShape aM;
|
||||
BOPTools::MapShapes(E, TopAbs_VERTEX, aM);
|
||||
Standard_Integer i, anExtent, aN=10;
|
||||
Standard_Real ln=0., d, t, f, l, dt;
|
||||
anExtent=aM.Extent();
|
||||
|
||||
if (anExtent!=1)
|
||||
return Standard_True;
|
||||
|
||||
gp_Pnt p1, p2;
|
||||
f = BC.FirstParameter();
|
||||
l = BC.LastParameter();
|
||||
dt=(l-f)/aN;
|
||||
|
||||
BC.D0(f, p1);
|
||||
for (i=1; i<=aN; i++) {
|
||||
t=f+i*dt;
|
||||
|
||||
if (i==aN)
|
||||
BC.D0(l, p2);
|
||||
else
|
||||
BC.D0(t, p2);
|
||||
|
||||
d=p1.Distance(p2);
|
||||
ln+=d;
|
||||
p1=p2;
|
||||
}
|
||||
//
|
||||
return (ln > Precision::Confusion());
|
||||
}
|
||||
//=======================================================================
|
||||
//function : BRep_Tool_CurveOnSurface
|
||||
//purpose :
|
||||
|
@@ -113,6 +113,14 @@ static
|
||||
const Standard_Real aTol,
|
||||
const BOPCol_IndexedMapOfShape& aMapToAvoid);
|
||||
|
||||
static
|
||||
Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
|
||||
const TopoDS_Face& theF,
|
||||
const Handle(Geom_Surface)& theS,
|
||||
const TopoDS_Edge& theE1,
|
||||
const TopoDS_Edge& theE2,
|
||||
NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen);
|
||||
|
||||
//=======================================================================
|
||||
//class : BOPTools_CPC
|
||||
//purpose :
|
||||
@@ -469,43 +477,55 @@ void CheckEdge (const TopoDS_Edge& Ed,
|
||||
const Standard_Real aMaxTol,
|
||||
const BOPCol_IndexedMapOfShape& aMapToAvoid)
|
||||
{
|
||||
TopoDS_Edge aE = Ed;
|
||||
Standard_Real aTolE, aTol, aD2, aNewTolerance, dd;
|
||||
gp_Pnt aPC;
|
||||
TopLoc_Location L;
|
||||
TopoDS_Edge aE;
|
||||
TopoDS_Vertex aV;
|
||||
TopoDS_Iterator aItS;
|
||||
//
|
||||
TopAbs_Orientation aOrV;
|
||||
BRep_ListIteratorOfListOfPointRepresentation aItPR;
|
||||
BRep_ListIteratorOfListOfCurveRepresentation aItCR;
|
||||
//
|
||||
aE=Ed;
|
||||
aE.Orientation(TopAbs_FORWARD);
|
||||
Standard_Real aTolE = BRep_Tool::Tolerance(aE);
|
||||
aTolE=BRep_Tool::Tolerance(aE);
|
||||
//
|
||||
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
|
||||
//
|
||||
const TopLoc_Location& Eloc = aE.Location();
|
||||
|
||||
TopoDS_Iterator aItS(aE);
|
||||
aItS.Initialize(aE);
|
||||
for (; aItS.More(); aItS.Next()) {
|
||||
const TopoDS_Vertex& aV= TopoDS::Vertex(aItS.Value());
|
||||
aV= TopoDS::Vertex(aItS.Value());
|
||||
//
|
||||
Handle(BRep_TVertex)& TV=*((Handle(BRep_TVertex)*)&aV.TShape());
|
||||
const gp_Pnt& aPV = TV->Pnt();
|
||||
//
|
||||
Standard_Real aTol=BRep_Tool::Tolerance(aV);
|
||||
aTol=BRep_Tool::Tolerance(aV);
|
||||
aTol=Max(aTol, aTolE);
|
||||
Standard_Real dd=0.1*aTol;
|
||||
dd=0.1*aTol;
|
||||
aTol*=aTol;
|
||||
//
|
||||
BRep_ListIteratorOfListOfCurveRepresentation aItCR(TE->Curves());
|
||||
const TopLoc_Location& Eloc = aE.Location();
|
||||
//
|
||||
aItCR.Initialize(TE->Curves());
|
||||
while (aItCR.More()) {
|
||||
const Handle(BRep_CurveRepresentation)& aCR = aItCR.Value();
|
||||
const TopLoc_Location& loc = aCR->Location();
|
||||
L = (Eloc * loc).Predivided(aV.Location());
|
||||
//
|
||||
if (aCR->IsCurve3D()) {
|
||||
const Handle(Geom_Curve)& aC = aCR->Curve3D();
|
||||
if (!aC.IsNull()) {
|
||||
TopLoc_Location L = (Eloc * aCR->Location()).Predivided(aV.Location());
|
||||
BRep_ListIteratorOfListOfPointRepresentation aItPR(TV->Points());
|
||||
aItPR.Initialize(TV->Points());
|
||||
while (aItPR.More()) {
|
||||
const Handle(BRep_PointRepresentation)& aPR=aItPR.Value();
|
||||
if (aPR->IsPointOnCurve(aC, L)) {
|
||||
gp_Pnt aPC = aC->Value(aPR->Parameter());
|
||||
aPC = aC->Value(aPR->Parameter());
|
||||
aPC.Transform(L.Transformation());
|
||||
Standard_Real aD2=aPV.SquareDistance(aPC);
|
||||
aD2=aPV.SquareDistance(aPC);
|
||||
if (aD2 > aTol) {
|
||||
Standard_Real aNewTolerance=sqrt(aD2)+dd;
|
||||
aNewTolerance=sqrt(aD2)+dd;
|
||||
if (aNewTolerance<aMaxTol)
|
||||
UpdateShape(aV, aNewTolerance, aMapToAvoid);
|
||||
}
|
||||
@@ -513,10 +533,10 @@ void CheckEdge (const TopoDS_Edge& Ed,
|
||||
aItPR.Next();
|
||||
}
|
||||
//
|
||||
TopAbs_Orientation aOrV=aV.Orientation();
|
||||
aOrV=aV.Orientation();
|
||||
if (aOrV==TopAbs_FORWARD || aOrV==TopAbs_REVERSED) {
|
||||
Handle(BRep_GCurve) aGC (Handle(BRep_GCurve)::DownCast (aCR));
|
||||
gp_Pnt aPC;
|
||||
|
||||
if (aOrV==TopAbs_FORWARD) {
|
||||
aPC=aC->Value(aGC->First());
|
||||
}
|
||||
@@ -525,9 +545,9 @@ void CheckEdge (const TopoDS_Edge& Ed,
|
||||
}
|
||||
aPC.Transform(L.Transformation());
|
||||
//
|
||||
Standard_Real aD2=aPV.SquareDistance(aPC);
|
||||
aD2=aPV.SquareDistance(aPC);
|
||||
if (aD2 > aTol) {
|
||||
Standard_Real aNewTolerance=sqrt(aD2)+dd;
|
||||
aNewTolerance=sqrt(aD2)+dd;
|
||||
if (aNewTolerance<aMaxTol)
|
||||
UpdateShape(aV, aNewTolerance, aMapToAvoid);
|
||||
}
|
||||
@@ -538,6 +558,80 @@ void CheckEdge (const TopoDS_Edge& Ed,
|
||||
}// while (itcr.More()) {
|
||||
} // for (; aVExp.More(); aVExp.Next()) {
|
||||
}
|
||||
//=======================================================================
|
||||
// Function : CorrectWires
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
void CorrectWires(const TopoDS_Face& aFx,
|
||||
const BOPCol_IndexedMapOfShape& aMapToAvoid)
|
||||
{
|
||||
Standard_Integer i, aNbV;
|
||||
Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
|
||||
gp_Pnt aP, aPV;
|
||||
gp_Pnt2d aP2D;
|
||||
TopoDS_Face aF;
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMVE;
|
||||
TopTools_ListIteratorOfListOfShape aIt, aIt1;
|
||||
//
|
||||
aF=aFx;
|
||||
aF.Orientation(TopAbs_FORWARD);
|
||||
const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
|
||||
//
|
||||
TopExp::MapShapesAndAncestors(aF,
|
||||
TopAbs_VERTEX,
|
||||
TopAbs_EDGE,
|
||||
aMVE);
|
||||
NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
|
||||
aNbV=aMVE.Extent();
|
||||
for (i=1; i<=aNbV; ++i) {
|
||||
const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
|
||||
aPV=BRep_Tool::Pnt(aV);
|
||||
aTol=BRep_Tool::Tolerance(aV);
|
||||
aTol2=aTol*aTol;
|
||||
//
|
||||
aD2max=-1.;
|
||||
const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
|
||||
aIt.Initialize(aLE);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
|
||||
const Handle(Geom2d_Curve)& aC2D=
|
||||
BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
|
||||
aT=BRep_Tool::Parameter(aV, aE);
|
||||
//
|
||||
aC2D->D0(aT, aP2D);
|
||||
aS->D0(aP2D.X(), aP2D.Y(), aP);
|
||||
aD2=aPV.SquareDistance(aP);
|
||||
if (aD2>aD2max) {
|
||||
aD2max=aD2;
|
||||
}
|
||||
}
|
||||
//
|
||||
//check wires on self interference by intersecting 2d curves of the edges
|
||||
aIt.Initialize(aLE);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Edge& aE1 = *(TopoDS_Edge*)&aIt.Value();
|
||||
//
|
||||
aIt1 = aIt;
|
||||
for (aIt1.Next(); aIt1.More(); aIt1.Next()) {
|
||||
const TopoDS_Edge& aE2 = *(TopoDS_Edge*)&aIt1.Value();
|
||||
//
|
||||
if (aE1.IsSame(aE2)) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
aD2 = IntersectCurves2d(aV, aF, aS, aE1, aE2, aMapEdgeLen);
|
||||
if (aD2 > aD2max) {
|
||||
aD2max = aD2;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
if (aD2max>aTol2) {
|
||||
aTol = 1.01 * sqrt(aD2max);
|
||||
UpdateShape(aV, aTol, aMapToAvoid);
|
||||
}
|
||||
}// for (i=1; i<=aNbV; ++i) {
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// Function : MapEdgeLength
|
||||
@@ -559,48 +653,35 @@ static Standard_Real MapEdgeLength(const TopoDS_Edge& theEdge,
|
||||
}
|
||||
return *pLen;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// Function : EdgeData
|
||||
// purpose : Structure to store edge data
|
||||
//=======================================================================
|
||||
namespace {
|
||||
struct EdgeData {
|
||||
const TopoDS_Edge* Edge; // Edge
|
||||
Standard_Real VParameter; // Parameter of the vertex on the edge
|
||||
Geom2dAdaptor_Curve GAdaptor; // 2D adaptor for PCurve of the edge on the face
|
||||
Standard_Real First; // First parameter in the range
|
||||
Standard_Real Last; // Last parameter in the rage
|
||||
};
|
||||
}
|
||||
//=======================================================================
|
||||
// Function : IntersectCurves2d
|
||||
// purpose : Intersect 2d curves of edges
|
||||
//=======================================================================
|
||||
static
|
||||
Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
|
||||
const TopoDS_Face& theF,
|
||||
const Handle(Geom_Surface)& theS,
|
||||
const EdgeData& theEData1,
|
||||
const EdgeData& theEData2,
|
||||
const TopoDS_Edge& theE1,
|
||||
const TopoDS_Edge& theE2,
|
||||
NCollection_DataMap<TopoDS_Shape, Standard_Real>& theMapEdgeLen)
|
||||
{
|
||||
Standard_Real aT11, aT12, aT21, aT22, aTol2d, aMaxDist;
|
||||
Geom2dInt_GInter anInter;
|
||||
// Range of the first edge
|
||||
Standard_Real aT11 = theEData1.First;
|
||||
Standard_Real aT12 = theEData1.Last;
|
||||
// Range of the second edge
|
||||
Standard_Real aT21 = theEData2.First;
|
||||
Standard_Real aT22 = theEData2.Last;
|
||||
|
||||
Standard_Real aMaxDist = 0.;
|
||||
Standard_Real aTol2d = 1.e-10;
|
||||
//
|
||||
IntRes2d_Domain aDom1(theEData1.GAdaptor.Value(aT11), aT11, aTol2d,
|
||||
theEData1.GAdaptor.Value(aT12), aT12, aTol2d);
|
||||
IntRes2d_Domain aDom2(theEData2.GAdaptor.Value(aT21), aT21, aTol2d,
|
||||
theEData2.GAdaptor.Value(aT22), aT22, aTol2d);
|
||||
aMaxDist = 0.;
|
||||
aTol2d = 1.e-10;
|
||||
//
|
||||
anInter.Perform(theEData1.GAdaptor, aDom1, theEData2.GAdaptor, aDom2, aTol2d, aTol2d);
|
||||
const Handle(Geom2d_Curve)& aC2D1=
|
||||
BRep_Tool::CurveOnSurface(theE1, theF, aT11, aT12);
|
||||
const Handle(Geom2d_Curve)& aC2D2=
|
||||
BRep_Tool::CurveOnSurface(theE2, theF, aT21, aT22);
|
||||
//
|
||||
Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
|
||||
IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d,
|
||||
aC2D1->Value(aT12), aT12, aTol2d);
|
||||
IntRes2d_Domain aDom2(aC2D2->Value(aT21), aT21, aTol2d,
|
||||
aC2D2->Value(aT22), aT22, aTol2d);
|
||||
//
|
||||
anInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
|
||||
if (!anInter.IsDone() || (!anInter.NbSegments() && !anInter.NbPoints())) {
|
||||
return aMaxDist;
|
||||
}
|
||||
@@ -613,8 +694,8 @@ static
|
||||
NCollection_List<IntRes2d_IntersectionPoint>::Iterator aItLP;
|
||||
//
|
||||
aPV = BRep_Tool::Pnt(theV);
|
||||
aT1 = theEData1.VParameter;
|
||||
aT2 = theEData2.VParameter;
|
||||
aT1 = BRep_Tool::Parameter(theV, theE1);
|
||||
aT2 = BRep_Tool::Parameter(theV, theE2);
|
||||
//
|
||||
aHalfR1 = (aT12 - aT11) / 2.;
|
||||
aHalfR2 = (aT22 - aT21) / 2.;
|
||||
@@ -635,8 +716,8 @@ static
|
||||
}
|
||||
//
|
||||
// evaluate the length of the smallest edge, so that not to return too large distance
|
||||
Standard_Real aLen1 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
|
||||
Standard_Real aLen2 = MapEdgeLength(*theEData1.Edge, theMapEdgeLen);
|
||||
Standard_Real aLen1 = MapEdgeLength(theE1, theMapEdgeLen);
|
||||
Standard_Real aLen2 = MapEdgeLength(theE2, theMapEdgeLen);
|
||||
const Standard_Real MaxEdgePartCoveredByVertex = 0.3;
|
||||
Standard_Real aMaxThresDist = Min(aLen1, aLen2) * MaxEdgePartCoveredByVertex;
|
||||
aMaxThresDist *= aMaxThresDist;
|
||||
@@ -669,86 +750,6 @@ static
|
||||
//
|
||||
return aMaxDist;
|
||||
}
|
||||
//=======================================================================
|
||||
// Function : CorrectWires
|
||||
// purpose :
|
||||
//=======================================================================
|
||||
void CorrectWires(const TopoDS_Face& aFx,
|
||||
const BOPCol_IndexedMapOfShape& aMapToAvoid)
|
||||
{
|
||||
Standard_Integer i, aNbV;
|
||||
Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
|
||||
gp_Pnt aP, aPV;
|
||||
gp_Pnt2d aP2D;
|
||||
TopoDS_Face aF;
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMVE;
|
||||
TopTools_ListIteratorOfListOfShape aIt;
|
||||
//
|
||||
aF=aFx;
|
||||
aF.Orientation(TopAbs_FORWARD);
|
||||
const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
|
||||
//
|
||||
TopExp::MapShapesAndAncestors(aF,
|
||||
TopAbs_VERTEX,
|
||||
TopAbs_EDGE,
|
||||
aMVE);
|
||||
NCollection_DataMap<TopoDS_Shape, Standard_Real> aMapEdgeLen;
|
||||
aNbV=aMVE.Extent();
|
||||
for (i=1; i<=aNbV; ++i) {
|
||||
const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMVE.FindKey(i));
|
||||
aPV=BRep_Tool::Pnt(aV);
|
||||
aTol=BRep_Tool::Tolerance(aV);
|
||||
aTol2=aTol*aTol;
|
||||
//
|
||||
aD2max=-1.;
|
||||
// Save edge's data to avoid its recalculation during intersection of 2d curves
|
||||
NCollection_List<EdgeData> aLEPars;
|
||||
const TopTools_ListOfShape& aLE=aMVE.FindFromIndex(i);
|
||||
aIt.Initialize(aLE);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aIt.Value());
|
||||
const Handle(Geom2d_Curve)& aC2D=
|
||||
BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
|
||||
aT=BRep_Tool::Parameter(aV, aE);
|
||||
//
|
||||
aC2D->D0(aT, aP2D);
|
||||
aS->D0(aP2D.X(), aP2D.Y(), aP);
|
||||
aD2=aPV.SquareDistance(aP);
|
||||
if (aD2>aD2max) {
|
||||
aD2max=aD2;
|
||||
}
|
||||
EdgeData anEData = {&aE, aT, Geom2dAdaptor_Curve(aC2D), aT1, aT2};
|
||||
aLEPars.Append(anEData);
|
||||
}
|
||||
//
|
||||
//check wires on self interference by intersecting 2d curves of the edges
|
||||
NCollection_List<EdgeData>::Iterator aItE1(aLEPars);
|
||||
for (; aItE1.More(); aItE1.Next()) {
|
||||
const EdgeData& aEData1 = aItE1.Value();
|
||||
const TopoDS_Shape& aE1 = *aEData1.Edge;
|
||||
|
||||
NCollection_List<EdgeData>::Iterator aItE2 = aItE1;
|
||||
for (aItE2.Next(); aItE2.More(); aItE2.Next()) {
|
||||
const EdgeData& aEData2 = aItE2.Value();
|
||||
const TopoDS_Shape& aE2 = *aEData2.Edge;
|
||||
|
||||
if (aE1.IsSame(aE2))
|
||||
continue;
|
||||
|
||||
aD2 = IntersectCurves2d(aV, aS, aEData1, aEData2, aMapEdgeLen);
|
||||
if (aD2 > aD2max) {
|
||||
aD2max = aD2;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
if (aD2max>aTol2) {
|
||||
aTol = 1.01 * sqrt(aD2max);
|
||||
UpdateShape(aV, aTol, aMapToAvoid);
|
||||
}
|
||||
}// for (i=1; i<=aNbV; ++i) {
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
// Function : CorrectEdgeTolerance
|
||||
// purpose : Correct tolerances for Edge
|
||||
|
@@ -55,7 +55,6 @@ public:
|
||||
using BOPAlgo_Options::ClearWarnings;
|
||||
using BOPAlgo_Options::GetReport;
|
||||
using BOPAlgo_Options::SetProgressIndicator;
|
||||
using BOPAlgo_Options::SetCheckInverted;
|
||||
|
||||
protected:
|
||||
|
||||
|
@@ -353,7 +353,6 @@ void BRepAlgoAPI_BooleanOperation::Build()
|
||||
//
|
||||
myBuilder->SetRunParallel(myRunParallel);
|
||||
myBuilder->SetProgressIndicator(myProgressIndicator);
|
||||
myBuilder->SetCheckInverted(myCheckInverted);
|
||||
//
|
||||
myBuilder->PerformWithFiller(*myDSFiller);
|
||||
//
|
||||
|
@@ -163,7 +163,6 @@ void BRepAlgoAPI_BuilderAlgo::Build()
|
||||
//
|
||||
myBuilder->SetRunParallel(myRunParallel);
|
||||
myBuilder->SetProgressIndicator(myProgressIndicator);
|
||||
myBuilder->SetCheckInverted(myCheckInverted);
|
||||
//
|
||||
myBuilder->PerformWithFiller(*myDSFiller);
|
||||
//
|
||||
|
@@ -121,7 +121,6 @@ void BRepAlgoAPI_Splitter::Build()
|
||||
//
|
||||
myBuilder->SetRunParallel(myRunParallel);
|
||||
myBuilder->SetProgressIndicator(myProgressIndicator);
|
||||
myBuilder->SetCheckInverted(myCheckInverted);
|
||||
//
|
||||
myBuilder->PerformWithFiller(*myDSFiller);
|
||||
//
|
||||
|
@@ -185,6 +185,8 @@ private:
|
||||
Standard_Boolean myCopyMesh;
|
||||
};
|
||||
|
||||
DEFINE_STANDARD_HANDLE(BRepBuilderAPI_Copy_Modification, BRepTools_Modification)
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -2365,7 +2365,6 @@ void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
|
||||
#endif
|
||||
Standard_Real U1 = 0.,U2 = 0.;
|
||||
gp_Pnt2d P2d;
|
||||
Standard_Boolean aCurrentFind = Standard_False;
|
||||
if (itry == 1) {
|
||||
fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
|
||||
fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
|
||||
@@ -2385,7 +2384,6 @@ void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
|
||||
Abs(fl2[i2]) < Precision::Infinite() ) {
|
||||
if (P1[i1].IsEqual(P2[i2],TolConf)) {
|
||||
YaSol = Standard_True;
|
||||
aCurrentFind = Standard_True;
|
||||
U1 = fl1[i1]; U2 = fl2[i2];
|
||||
P2d = C1->Value(U1);
|
||||
}
|
||||
@@ -2412,7 +2410,6 @@ void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
|
||||
if (Dist2Min <= Precision::SquareConfusion())
|
||||
{
|
||||
YaSol = Standard_True;
|
||||
aCurrentFind = Standard_True;
|
||||
P2d = P1[i1];
|
||||
U1 = fl1[i1];
|
||||
U2 = (extr.Point(IndexMin)).Parameter();
|
||||
@@ -2440,7 +2437,6 @@ void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
|
||||
if (Dist2Min <= Precision::SquareConfusion())
|
||||
{
|
||||
YaSol = Standard_True;
|
||||
aCurrentFind = Standard_True;
|
||||
P2d = P2[i2];
|
||||
U2 = fl2[i2];
|
||||
U1 = (extr.Point(IndexMin)).Parameter();
|
||||
@@ -2455,14 +2451,12 @@ void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
|
||||
|
||||
if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
|
||||
YaSol = Standard_True;
|
||||
aCurrentFind = Standard_True;
|
||||
U1 = Inter.Point(1).ParamOnFirst();
|
||||
U2 = Inter.Point(1).ParamOnSecond();
|
||||
P2d = Inter.Point(1).Value();
|
||||
}
|
||||
else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
|
||||
YaSol = Standard_True;
|
||||
aCurrentFind = Standard_True;
|
||||
IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
|
||||
IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
|
||||
IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
|
||||
@@ -2485,7 +2479,7 @@ void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
|
||||
P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
|
||||
}
|
||||
}
|
||||
if (aCurrentFind) {
|
||||
if (YaSol) {
|
||||
gp_Pnt P = S->Value(P2d.X(),P2d.Y());
|
||||
TopoDS_Vertex V = BRepLib_MakeVertex(P);
|
||||
V.Orientation(TopAbs_INTERNAL);
|
||||
|
@@ -240,12 +240,12 @@ static gp_Pnt findCommonPoint(const TopoDS_Shape& W)
|
||||
// The common point for two edges inside a wire
|
||||
// is a sharing vertex of two edges.
|
||||
TopTools_MapOfShape vertices;
|
||||
TopExp_Explorer aExp(W, TopAbs_VERTEX);
|
||||
for (; aExp.More(); aExp.Next())
|
||||
TopExp_Explorer expl(W, TopAbs_VERTEX);
|
||||
for (; expl.More(); expl.Next())
|
||||
{
|
||||
if (!vertices.Add(aExp.Current()))
|
||||
if (!vertices.Add(expl.Current()))
|
||||
{
|
||||
return BRep_Tool::Pnt(TopoDS::Vertex(aExp.Current()));
|
||||
return BRep_Tool::Pnt(TopoDS::Vertex(expl.Current()));
|
||||
}
|
||||
}
|
||||
return gp::Origin(); // not found
|
||||
|
@@ -1140,7 +1140,6 @@ static Standard_Integer normals (Draw_Interpretor& theDI,
|
||||
Standard_Boolean toUseMesh = Standard_False;
|
||||
Standard_Real aLength = 10.0;
|
||||
Standard_Integer aNbAlongU = 1, aNbAlongV = 1;
|
||||
Standard_Boolean bPrint = Standard_False;
|
||||
for (Standard_Integer anArgIter = 2; anArgIter< theArgNum; ++anArgIter)
|
||||
{
|
||||
TCollection_AsciiString aParam (theArgs[anArgIter]);
|
||||
@@ -1205,13 +1204,9 @@ static Standard_Integer normals (Draw_Interpretor& theDI,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (aParam == "-print")
|
||||
{
|
||||
bPrint = Standard_True;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Syntax error: unknown argument '" << aParam << "'\n";
|
||||
std::cout << "Syntax error: unknwon argument '" << aParam << "'\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1230,29 +1225,12 @@ static Standard_Integer normals (Draw_Interpretor& theDI,
|
||||
|
||||
for (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >::Iterator aFaceIt (aNormals); aFaceIt.More(); aFaceIt.Next())
|
||||
{
|
||||
Standard_Boolean bReverse = Standard_False;
|
||||
TopAbs_Orientation aFaceOri = aFaceIt.Key().Orientation();
|
||||
const Draw_Color aColor = DBRep_ColorOrientation (aFaceOri);
|
||||
if (aFaceOri == TopAbs_REVERSED)
|
||||
bReverse = Standard_True;
|
||||
|
||||
const Draw_Color aColor = DBRep_ColorOrientation (aFaceIt.Key().Orientation());
|
||||
for (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >::Iterator aNormalsIt (aFaceIt.Value()); aNormalsIt.More(); aNormalsIt.Next())
|
||||
{
|
||||
const std::pair<gp_Pnt, gp_Pnt>& aVec = aNormalsIt.Value();
|
||||
Handle(Draw_Segment3D) aSeg = new Draw_Segment3D(aVec.first, aVec.second, aColor);
|
||||
dout << aSeg;
|
||||
if (bPrint)
|
||||
{
|
||||
// Make the normal vector from the points
|
||||
gp_Vec aV(aVec.first, aVec.second);
|
||||
if (bReverse)
|
||||
aV.Reverse();
|
||||
|
||||
// Print values of the vector avoiding printing "-0" values
|
||||
theDI << "(" << (aV.X() == 0 ? 0 : aV.X()) << ", "
|
||||
<< (aV.Y() == 0 ? 0 : aV.Y()) << ", "
|
||||
<< (aV.Z() == 0 ? 0 : aV.Z()) << ")\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1428,7 +1406,7 @@ void DBRep::BasicCommands(Draw_Interpretor& theCommands)
|
||||
theCommands.Add("treverse","treverse name1 name2 ...",__FILE__,orientation,g);
|
||||
theCommands.Add("complement","complement name1 name2 ...",__FILE__,orientation,g);
|
||||
theCommands.Add("invert","invert name, reverse subshapes",__FILE__,invert,g);
|
||||
theCommands.Add("normals","normals shape [Length {10}] [-NbAlongU {1}] [-NbAlongV {1}] [-UseMesh] [-print], display normals",__FILE__,normals,g);
|
||||
theCommands.Add("normals","normals shape [Length {10}] [-NbAlongU {1}] [-NbAlongV {1}] [-UseMesh], display normals",__FILE__,normals,g);
|
||||
theCommands.Add("nbshapes",
|
||||
"\n nbshapes s - shows the number of sub-shapes in <s>;\n nbshapes s -t - shows the number of sub-shapes in <s> counting the same sub-shapes with different location as different sub-shapes.",
|
||||
__FILE__,nbshapes,g);
|
||||
|
@@ -1075,9 +1075,13 @@ void DBRep_DrawableShape::display(const Handle(Poly_Triangulation)& T,
|
||||
|
||||
// allocate the arrays
|
||||
TColStd_Array1OfInteger Free (1, Max (1, 2 * nFree));
|
||||
NCollection_Vector< NCollection_Vec2<Standard_Integer> > anInternal;
|
||||
|
||||
Standard_Integer fr = 1;
|
||||
// array is replaced on map because it is impossible
|
||||
// to calculate number of internal edges in advance
|
||||
// due to "internal edges"
|
||||
TColStd_DataMapOfIntegerInteger Internal;
|
||||
|
||||
Standard_Integer fr = 1, in = 1;
|
||||
const Poly_Array1OfTriangle& triangles = T->Triangles();
|
||||
Standard_Integer n[3];
|
||||
for (i = 1; i <= nbTriangles; i++) {
|
||||
@@ -1092,7 +1096,9 @@ void DBRep_DrawableShape::display(const Handle(Poly_Triangulation)& T,
|
||||
}
|
||||
// internal edge if this triangle has a lower index than the adjacent
|
||||
else if (i < t[j]) {
|
||||
anInternal.Append (NCollection_Vec2<Standard_Integer> (n[j], n[k]));
|
||||
Internal.Bind(in, n[j]);
|
||||
Internal.Bind(in+1, n[k]);
|
||||
in += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1113,11 +1119,15 @@ void DBRep_DrawableShape::display(const Handle(Poly_Triangulation)& T,
|
||||
// internal edges
|
||||
|
||||
dis.SetColor(Draw_bleu);
|
||||
for (NCollection_Vector< NCollection_Vec2<Standard_Integer> >::Iterator anInterIter (anInternal); anInterIter.More(); anInterIter.Next())
|
||||
{
|
||||
const Standard_Integer n1 = anInterIter.Value()[0];
|
||||
const Standard_Integer n2 = anInterIter.Value()[1];
|
||||
dis.Draw (Nodes(n1).Transformed(tr), Nodes(n2).Transformed(tr));
|
||||
TColStd_DataMapIteratorOfDataMapOfIntegerInteger aIt(Internal);
|
||||
for (; aIt.More(); aIt.Next()) {
|
||||
Standard_Integer n1 = aIt.Value();
|
||||
//alvays pair is put
|
||||
aIt.Next();
|
||||
Standard_Integer n2 = aIt.Value();
|
||||
dis.Draw(Nodes(n1).Transformed(tr),
|
||||
Nodes(n2).Transformed(tr));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -364,20 +364,20 @@ static void LoadNextLevels(const TopoDS_Shape& S,
|
||||
{
|
||||
|
||||
if (S.ShapeType() == TopAbs_SOLID) {
|
||||
TopExp_Explorer aExp(S, TopAbs_FACE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
TopExp_Explorer expl(S, TopAbs_FACE);
|
||||
for (; expl.More(); expl.Next()) {
|
||||
TNaming_Builder bFace(Tagger->NewChild());
|
||||
bFace.Generated(aExp.Current());
|
||||
bFace.Generated(expl.Current());
|
||||
}
|
||||
} else if (S.ShapeType() == TopAbs_SHELL || S.ShapeType() == TopAbs_FACE) {
|
||||
// load faces and all the free edges
|
||||
TopTools_IndexedMapOfShape Faces;
|
||||
TopExp::MapShapes(S, TopAbs_FACE, Faces);
|
||||
if (Faces.Extent() > 1 || (S.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) {
|
||||
TopExp_Explorer aExp(S, TopAbs_FACE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
TopExp_Explorer expl(S, TopAbs_FACE);
|
||||
for (; expl.More(); expl.Next()) {
|
||||
TNaming_Builder bFace(Tagger->NewChild());
|
||||
bFace.Generated(aExp.Current());
|
||||
bFace.Generated(expl.Current());
|
||||
}
|
||||
}
|
||||
TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces;
|
||||
@@ -403,16 +403,16 @@ static void LoadNextLevels(const TopoDS_Shape& S,
|
||||
if (Edges.Extent() == 1) {
|
||||
TNaming_Builder bEdge(Tagger->NewChild());
|
||||
bEdge.Generated(Edges.FindKey(1));
|
||||
TopExp_Explorer aExp(S, TopAbs_VERTEX);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
TopExp_Explorer expl(S, TopAbs_VERTEX);
|
||||
for (; expl.More(); expl.Next()) {
|
||||
TNaming_Builder bVertex(Tagger->NewChild());
|
||||
bVertex.Generated(aExp.Current());
|
||||
bVertex.Generated(expl.Current());
|
||||
}
|
||||
} else {
|
||||
TopExp_Explorer aExp(S, TopAbs_EDGE);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
TopExp_Explorer expl(S, TopAbs_EDGE);
|
||||
for (; expl.More(); expl.Next()) {
|
||||
TNaming_Builder bEdge(Tagger->NewChild());
|
||||
bEdge.Generated(aExp.Current());
|
||||
bEdge.Generated(expl.Current());
|
||||
}
|
||||
// and load generated vertices.
|
||||
TopTools_DataMapOfShapeShape generated;
|
||||
@@ -422,10 +422,10 @@ static void LoadNextLevels(const TopoDS_Shape& S,
|
||||
}
|
||||
}
|
||||
} else if (S.ShapeType() == TopAbs_EDGE) {
|
||||
TopExp_Explorer aExp(S, TopAbs_VERTEX);
|
||||
for (; aExp.More(); aExp.Next()) {
|
||||
TopExp_Explorer expl(S, TopAbs_VERTEX);
|
||||
for (; expl.More(); expl.Next()) {
|
||||
TNaming_Builder bVertex(Tagger->NewChild());
|
||||
bVertex.Generated(aExp.Current());
|
||||
bVertex.Generated(expl.Current());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -277,10 +277,10 @@ Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
|
||||
}
|
||||
}
|
||||
|
||||
TopExp_Explorer aExp(F,TopAbs_EDGE);
|
||||
TopExp_Explorer expl(F,TopAbs_EDGE);
|
||||
TopTools_MapOfShape MapOfE;
|
||||
while (aExp.More() && badShape.IsNull()) {
|
||||
const TopoDS_Edge& edg = TopoDS::Edge(aExp.Current());
|
||||
while (expl.More() && badShape.IsNull()) {
|
||||
const TopoDS_Edge& edg = TopoDS::Edge(expl.Current());
|
||||
if (!myEMap.Contains(edg)) {
|
||||
Standard_Boolean addedg = Standard_False;
|
||||
Standard_Boolean addface = Standard_False;
|
||||
@@ -393,7 +393,7 @@ Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
|
||||
}
|
||||
}
|
||||
}
|
||||
aExp.Next();
|
||||
expl.Next();
|
||||
}
|
||||
return (badShape.IsNull());
|
||||
}
|
||||
|
@@ -46,26 +46,26 @@ static FDraw_InitAppli theDraw_InitAppli; //pointer to the Draw_InitAppli
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
//=======================================================================
|
||||
//NOTE: OCC11
|
||||
// On Windows NT, both console (UNIX-like) and windowed (classical on
|
||||
// WNT, with three separated windows - input, output and graphic)
|
||||
// modes are supported.
|
||||
// Depending on compilation mode of executable (CONSOLE or WINDOWS),
|
||||
// either Draw_Main or Draw_WinMain becomes entry point;
|
||||
// either _main_ or _WinMain_ becomes entry point;
|
||||
// the further different behaviour of DRAW is determined by variable
|
||||
// Draw_IsConsoleSubsystem which is set by Draw_Main only
|
||||
// Draw_IsConsoleSubsystem which is set by _main_ only
|
||||
//=======================================================================
|
||||
|
||||
|
||||
extern Standard_Boolean Draw_IsConsoleSubsystem;
|
||||
|
||||
//=======================================================================
|
||||
//function : Draw_Main
|
||||
//function : _main_
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Draw_Main (int /*argc*/, char* argv[], const FDraw_InitAppli fDraw_InitAppli)
|
||||
Standard_Integer _main_ (int /*argc*/, char* argv[], char* /*envp*/[], const FDraw_InitAppli fDraw_InitAppli)
|
||||
{
|
||||
Draw_IsConsoleSubsystem = Standard_True;
|
||||
theDraw_InitAppli = fDraw_InitAppli;
|
||||
@@ -83,11 +83,11 @@ Standard_Integer Draw_Main (int /*argc*/, char* argv[], const FDraw_InitAppli fD
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Draw_WinMain
|
||||
//function : _WinMain_
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Draw_WinMain (HINSTANCE hInstance, HINSTANCE hPrevinstance, LPSTR /*lpCmdLine*/, int nCmdShow, const FDraw_InitAppli fDraw_InitAppli)
|
||||
Standard_Integer _WinMain_ (HINSTANCE hInstance, HINSTANCE hPrevinstance, LPSTR /*lpCmdLine*/, int nCmdShow, const FDraw_InitAppli fDraw_InitAppli)
|
||||
{
|
||||
theDraw_InitAppli = fDraw_InitAppli;
|
||||
int aNbArgs = 0;
|
||||
@@ -96,15 +96,13 @@ Standard_Integer Draw_WinMain (HINSTANCE hInstance, HINSTANCE hPrevinstance, LPS
|
||||
LocalFree (anArgVec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//=======================================================================
|
||||
//function : Draw_Main
|
||||
//function : _main_
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer Draw_Main (Standard_Integer argc, char* argv[], const FDraw_InitAppli fDraw_InitAppli)
|
||||
Standard_Integer _main_ (Standard_Integer argc, char* argv[], const FDraw_InitAppli fDraw_InitAppli)
|
||||
{
|
||||
// MKV 01.02.05
|
||||
#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)))
|
||||
@@ -113,5 +111,4 @@ Standard_Integer Draw_Main (Standard_Integer argc, char* argv[], const FDraw_Ini
|
||||
Draw_Appli(argc, argv, fDraw_InitAppli);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -30,32 +30,37 @@
|
||||
|
||||
typedef void (*FDraw_InitAppli)(Draw_Interpretor&);
|
||||
|
||||
Standard_EXPORT Standard_Integer Draw_Main (Standard_Integer argc, Standard_PCharacter argv[], const FDraw_InitAppli Draw_InitAppli);
|
||||
|
||||
// Declarations of macros DRAW_MAIN to be used in executables instead of explicit main/WinMain
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef _WIN32
|
||||
Standard_EXPORT Standard_Integer _main_ (Standard_Integer argc,
|
||||
Standard_PCharacter argv[],
|
||||
const FDraw_InitAppli Draw_InitAppli);
|
||||
#else
|
||||
#include <windows.h>
|
||||
|
||||
Standard_EXPORT Standard_Integer Draw_WinMain (HINSTANCE hInstance,
|
||||
Standard_EXPORT Standard_Integer _WinMain_ (HINSTANCE hInstance,
|
||||
HINSTANCE hPrevinstance,
|
||||
LPSTR lpCmdLine,
|
||||
Standard_Integer nCmdShow,
|
||||
const FDraw_InitAppli Draw_InitAppli);
|
||||
|
||||
// WinMain() and main()
|
||||
#define DRAW_MAIN Standard_Integer PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevinstance, LPSTR lpCmdLine, Standard_Integer nCmdShow) \
|
||||
{ return Draw_WinMain (hInstance, hPrevinstance, lpCmdLine, nCmdShow, Draw_InitAppli); } \
|
||||
\
|
||||
int main (int argc, char* argv[]) \
|
||||
{ return Draw_Main (argc, argv, Draw_InitAppli); }
|
||||
|
||||
#else
|
||||
Standard_EXPORT Standard_Integer _main_ (int argc,
|
||||
char* argv[],
|
||||
char* envp[],
|
||||
const FDraw_InitAppli Draw_InitAppli);
|
||||
#endif
|
||||
|
||||
// Declarations of macros DRAW_MAIN to be used in executables instead of explicit main/WinMain
|
||||
#ifndef _WIN32
|
||||
// main()
|
||||
#define DRAW_MAIN int main (Standard_Integer argc, char* argv[])\
|
||||
{ return Draw_Main (argc, argv, Draw_InitAppli); }
|
||||
|
||||
{return _main_ (argc, argv, Draw_InitAppli);}
|
||||
#else
|
||||
// WinMain() and main()
|
||||
#define DRAW_MAIN Standard_Integer PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevinstance, LPSTR lpCmdLine, Standard_Integer nCmdShow)\
|
||||
{return _WinMain_ (hInstance, hPrevinstance, lpCmdLine, nCmdShow, Draw_InitAppli);}\
|
||||
\
|
||||
int main (int argc, char* argv[], char* envp[])\
|
||||
{return _main_ (argc, argv, envp, Draw_InitAppli);}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -86,7 +86,7 @@ BOOL CreateProc(HWND hWndFrame)
|
||||
| COMMAND PROCEDURE
|
||||
| Handler for message WM_COMMAND
|
||||
| It is used when Draw_IsConsoleSubsystem = Standard_False
|
||||
| i.e. in non-console mode (see Draw_main() in Draw_Main.cxx).
|
||||
| i.e. in non-console mode (see _main_() in Draw_Main.cxx).
|
||||
\*--------------------------------------------------------------------------*/
|
||||
LRESULT APIENTRY CmdProc(HWND hWndFrame, UINT wMsg, WPARAM /*wParam*/, LPARAM /*lParam*/)
|
||||
{
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include <Graphic3d_AspectLine3d.hxx>
|
||||
#include <Graphic3d_AspectMarker3d.hxx>
|
||||
#include <Graphic3d_Group.hxx>
|
||||
#include <Graphic3d_Vertex.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Prs3d_Arrow.hxx>
|
||||
#include <Prs3d_ArrowAspect.hxx>
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include <Graphic3d_AspectLine3d.hxx>
|
||||
#include <Graphic3d_AspectMarker3d.hxx>
|
||||
#include <Graphic3d_Group.hxx>
|
||||
#include <Graphic3d_Vertex.hxx>
|
||||
#include <IntAna2d_AnaIntersection.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Prs3d_Arrow.hxx>
|
||||
|
@@ -764,6 +764,7 @@ gp_Vec GeomAdaptor_Curve::DN(const Standard_Real U,
|
||||
}
|
||||
else
|
||||
return myCurve->DN( U, N);
|
||||
break;
|
||||
}
|
||||
|
||||
case GeomAbs_OffsetCurve:
|
||||
|
@@ -353,8 +353,8 @@ GeomPlate_MakeApprox::GeomPlate_MakeApprox(const Handle(GeomPlate_Surface)& Surf
|
||||
|
||||
Standard_Real U0=0., U1=0., V0=0., V1=0.;
|
||||
myPlate->RealBounds(U0, U1, V0, V1);
|
||||
Standard_Real aDU = (U1 - U0) * (EnlargeCoeff - 1) * 0.5;
|
||||
Standard_Real aDV = (V1 - V0) * (EnlargeCoeff - 1) * 0.5;
|
||||
Standard_Real aDU = (U1 - U0) * (EnlargeCoeff - 1);
|
||||
Standard_Real aDV = (V1 - V0) * (EnlargeCoeff - 1);
|
||||
U0 = U0 - aDU;
|
||||
U1 = U1 + aDU;
|
||||
V0 = V0 - aDV;
|
||||
|
@@ -150,6 +150,9 @@ Graphic3d_Vec.hxx
|
||||
Graphic3d_Vec2.hxx
|
||||
Graphic3d_Vec3.hxx
|
||||
Graphic3d_Vec4.hxx
|
||||
Graphic3d_Vector.cxx
|
||||
Graphic3d_Vector.hxx
|
||||
Graphic3d_VectorError.hxx
|
||||
Graphic3d_Vertex.cxx
|
||||
Graphic3d_Vertex.hxx
|
||||
Graphic3d_VerticalTextAlignment.hxx
|
||||
|
@@ -53,7 +53,6 @@ public:
|
||||
OitDepthFactor (0.0f),
|
||||
NbMsaaSamples (0),
|
||||
RenderResolutionScale (1.0f),
|
||||
ToEnableDepthPrepass (Standard_False),
|
||||
// ray tracing parameters
|
||||
IsGlobalIlluminationEnabled (Standard_False),
|
||||
RaytracingDepth (THE_DEFAULT_DEPTH),
|
||||
@@ -106,7 +105,6 @@ 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)
|
||||
|
@@ -77,8 +77,6 @@ const TCollection_AsciiString& Graphic3d_ShaderProgram::ShadersFolder()
|
||||
// purpose : Creates new empty program object
|
||||
// =======================================================================
|
||||
Graphic3d_ShaderProgram::Graphic3d_ShaderProgram()
|
||||
: myNbLightsMax (THE_MAX_LIGHTS_DEFAULT),
|
||||
myNbClipPlanesMax (THE_MAX_CLIP_PLANES_DEFAULT)
|
||||
{
|
||||
myID = TCollection_AsciiString ("Graphic3d_ShaderProgram_")
|
||||
+ TCollection_AsciiString (Standard_Atomic_Increment (&THE_PROGRAM_OBJECT_COUNTER));
|
||||
|
@@ -34,14 +34,6 @@ typedef NCollection_Sequence<Handle(Graphic3d_ShaderAttribute)> Graphic3d_Shader
|
||||
//! This class is responsible for managing shader programs.
|
||||
class Graphic3d_ShaderProgram : public Standard_Transient
|
||||
{
|
||||
DEFINE_STANDARD_RTTIEXT(Graphic3d_ShaderProgram, Standard_Transient)
|
||||
public:
|
||||
|
||||
//! Default value of THE_MAX_LIGHTS macros within GLSL program (see Declarations.glsl).
|
||||
static const Standard_Integer THE_MAX_LIGHTS_DEFAULT = 8;
|
||||
|
||||
//! Default value of THE_MAX_CLIP_PLANES macros within GLSL program (see Declarations.glsl).
|
||||
static const Standard_Integer THE_MAX_CLIP_PLANES_DEFAULT = 8;
|
||||
|
||||
public:
|
||||
|
||||
@@ -69,32 +61,6 @@ public:
|
||||
//! @endcode
|
||||
void SetHeader (const TCollection_AsciiString& theHeader) { myHeader = theHeader; }
|
||||
|
||||
//! Append line to GLSL header.
|
||||
void AppendToHeader (const TCollection_AsciiString& theHeaderLine)
|
||||
{
|
||||
if (!myHeader.IsEmpty())
|
||||
{
|
||||
myHeader += "\n";
|
||||
}
|
||||
myHeader += theHeaderLine;
|
||||
}
|
||||
|
||||
//! Return the length of array of light sources (THE_MAX_LIGHTS),
|
||||
//! to be used for initialization occLightSources.
|
||||
//! Default value is THE_MAX_LIGHTS_DEFAULT.
|
||||
Standard_Integer NbLightsMax() const { return myNbLightsMax; }
|
||||
|
||||
//! Specify the length of array of light sources (THE_MAX_LIGHTS).
|
||||
void SetNbLightsMax (Standard_Integer theNbLights) { myNbLightsMax = theNbLights; }
|
||||
|
||||
//! Return the length of array of clipping planes (THE_MAX_CLIP_PLANES),
|
||||
//! to be used for initialization occClipPlaneEquations.
|
||||
//! Default value is THE_MAX_CLIP_PLANES_DEFAULT.
|
||||
Standard_Integer NbClipPlanesMax() const { return myNbClipPlanesMax; }
|
||||
|
||||
//! Specify the length of array of clipping planes (THE_MAX_CLIP_PLANES).
|
||||
void SetNbClipPlanesMax (Standard_Integer theNbPlanes) { myNbClipPlanesMax = theNbPlanes; }
|
||||
|
||||
//! Attaches shader object to the program object.
|
||||
Standard_EXPORT Standard_Boolean AttachShader (const Handle(Graphic3d_ShaderObject)& theShader);
|
||||
|
||||
@@ -155,6 +121,10 @@ public:
|
||||
//! @return the root folder with default GLSL programs.
|
||||
Standard_EXPORT static const TCollection_AsciiString& ShadersFolder();
|
||||
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(Graphic3d_ShaderProgram,Standard_Transient)
|
||||
|
||||
private:
|
||||
|
||||
TCollection_AsciiString myID; //!< the unique identifier of program object
|
||||
@@ -162,8 +132,6 @@ private:
|
||||
Graphic3d_ShaderVariableList myVariables; //!< the list of custom uniform variables
|
||||
Graphic3d_ShaderAttributeList myAttributes; //!< the list of custom vertex attributes
|
||||
TCollection_AsciiString myHeader; //!< GLSL header with version code and used extensions
|
||||
Standard_Integer myNbLightsMax; //!< length of array of light sources (THE_MAX_LIGHTS)
|
||||
Standard_Integer myNbClipPlanesMax; //!< length of array of clipping planes (THE_MAX_CLIP_PLANES)
|
||||
|
||||
};
|
||||
|
||||
|
@@ -26,7 +26,9 @@
|
||||
#include <Graphic3d_StructureDefinitionError.hxx>
|
||||
#include <Graphic3d_StructureManager.hxx>
|
||||
#include <Graphic3d_TransformError.hxx>
|
||||
#include <Graphic3d_Vector.hxx>
|
||||
#include <Quantity_Color.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include "Graphic3d_Structure.pxx"
|
||||
|
||||
|
@@ -47,6 +47,7 @@ class Graphic3d_StructureManager;
|
||||
class Graphic3d_DataStructureManager;
|
||||
class Bnd_Box;
|
||||
class gp_Pnt;
|
||||
class Graphic3d_Vector;
|
||||
|
||||
|
||||
class Graphic3d_Structure;
|
||||
|
188
src/Graphic3d/Graphic3d_Vector.cxx
Normal file
188
src/Graphic3d/Graphic3d_Vector.cxx
Normal file
@@ -0,0 +1,188 @@
|
||||
// Created by: NW,JPB,CAL
|
||||
// Copyright (c) 1991-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
// Modified 27/12/98 : FMN ; PERF: OPTIMISATION LOADER (LOPTIM)
|
||||
//-Version
|
||||
//-Design Declaration des variables specifiques aux vecteurs
|
||||
//-Warning Un vecteur est defini par ses composantes ou par
|
||||
// deux points
|
||||
// Il peut etre normalise
|
||||
//-References
|
||||
//-Language C++ 2.0
|
||||
//-Declarations
|
||||
// for the class
|
||||
|
||||
#include <Graphic3d_Vector.hxx>
|
||||
#include <Graphic3d_VectorError.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
|
||||
//-Aliases
|
||||
//-Global data definitions
|
||||
#define Graphic3d_Vector_MyEpsilon 0.000001
|
||||
|
||||
// -- les coordonnees du vecteur
|
||||
// MyX : Standard_ShortReal;
|
||||
// MyY : Standard_ShortReal;
|
||||
// MyZ : Standard_ShortReal;
|
||||
|
||||
// -- la norme du vecteur
|
||||
// MyNorme : Standard_ShortReal;
|
||||
|
||||
//-Constructors
|
||||
|
||||
Graphic3d_Vector::Graphic3d_Vector ():
|
||||
MyX (Standard_ShortReal (1.0)),
|
||||
MyY (Standard_ShortReal (1.0)),
|
||||
MyZ (Standard_ShortReal (1.0)),
|
||||
MyNorme (Standard_ShortReal (1.0)) {
|
||||
}
|
||||
|
||||
Graphic3d_Vector::Graphic3d_Vector (const Standard_Real AX, const Standard_Real AY, const Standard_Real AZ):
|
||||
MyX (Standard_ShortReal (AX)),
|
||||
MyY (Standard_ShortReal (AY)),
|
||||
MyZ (Standard_ShortReal (AZ)),
|
||||
MyNorme (Standard_ShortReal (Graphic3d_Vector::NormeOf (AX, AY, AZ))) {
|
||||
}
|
||||
|
||||
Graphic3d_Vector::Graphic3d_Vector (const Graphic3d_Vertex& APoint1, const Graphic3d_Vertex& APoint2) {
|
||||
|
||||
MyX = APoint2.X() - APoint1.X();
|
||||
MyY = APoint2.Y() - APoint1.Y();
|
||||
MyZ = APoint2.Z() - APoint1.Z();
|
||||
|
||||
MyNorme = Standard_ShortReal (Graphic3d_Vector::NormeOf (MyX, MyY, MyZ));
|
||||
|
||||
}
|
||||
|
||||
//-Destructors
|
||||
|
||||
//-Methods, in order
|
||||
|
||||
void Graphic3d_Vector::Coord (Standard_Real& AX, Standard_Real& AY, Standard_Real& AZ) const {
|
||||
|
||||
AX = Standard_Real (MyX);
|
||||
AY = Standard_Real (MyY);
|
||||
AZ = Standard_Real (MyZ);
|
||||
|
||||
}
|
||||
|
||||
Standard_Real Graphic3d_Vector::X () const {
|
||||
|
||||
return Standard_Real (MyX);
|
||||
|
||||
}
|
||||
|
||||
Standard_Real Graphic3d_Vector::Y () const {
|
||||
|
||||
return Standard_Real (MyY);
|
||||
|
||||
}
|
||||
|
||||
Standard_Real Graphic3d_Vector::Z () const {
|
||||
|
||||
return Standard_Real (MyZ);
|
||||
|
||||
}
|
||||
|
||||
void Graphic3d_Vector::Normalize () {
|
||||
|
||||
if (Abs (MyNorme) <= RealEpsilon ())
|
||||
throw Graphic3d_VectorError("The norm is null");
|
||||
|
||||
if (!IsNormalized()) // CQO CTS40181
|
||||
{
|
||||
MyX = MyX / MyNorme;
|
||||
MyY = MyY / MyNorme;
|
||||
MyZ = MyZ / MyNorme;
|
||||
}
|
||||
|
||||
MyNorme = Standard_ShortReal (1.0);
|
||||
|
||||
}
|
||||
|
||||
void Graphic3d_Vector::SetCoord (const Standard_Real Xnew, const Standard_Real Ynew, const Standard_Real Znew) {
|
||||
|
||||
MyX = Standard_ShortReal (Xnew);
|
||||
MyY = Standard_ShortReal (Ynew);
|
||||
MyZ = Standard_ShortReal (Znew);
|
||||
|
||||
MyNorme = Standard_ShortReal (Graphic3d_Vector::NormeOf (Standard_Real (MyX), Standard_Real (MyY), Standard_Real (MyZ)));
|
||||
|
||||
}
|
||||
|
||||
void Graphic3d_Vector::SetXCoord (const Standard_Real Xnew) {
|
||||
|
||||
MyX = Standard_ShortReal (Xnew);
|
||||
|
||||
MyNorme = Standard_ShortReal (Graphic3d_Vector::NormeOf (Standard_Real (MyX), Standard_Real (MyY), Standard_Real (MyZ)));
|
||||
|
||||
}
|
||||
|
||||
void Graphic3d_Vector::SetYCoord (const Standard_Real Ynew) {
|
||||
|
||||
MyY = Standard_ShortReal (Ynew);
|
||||
|
||||
MyNorme = Standard_ShortReal (Graphic3d_Vector::NormeOf (Standard_Real (MyX), Standard_Real (MyY), Standard_Real (MyZ)));
|
||||
|
||||
}
|
||||
|
||||
void Graphic3d_Vector::SetZCoord (const Standard_Real Znew) {
|
||||
|
||||
MyZ = Standard_ShortReal (Znew);
|
||||
|
||||
MyNorme = Standard_ShortReal (Graphic3d_Vector::NormeOf (Standard_Real (MyX), Standard_Real (MyY), Standard_Real (MyZ)));
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean Graphic3d_Vector::LengthZero () const {
|
||||
|
||||
return (Abs (Standard_Real (MyNorme)) <= RealEpsilon ());
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean Graphic3d_Vector::IsNormalized () const {
|
||||
|
||||
return (Abs (Standard_Real (MyNorme) - 1.0) <=
|
||||
Graphic3d_Vector_MyEpsilon);
|
||||
|
||||
}
|
||||
|
||||
Standard_Boolean Graphic3d_Vector::IsParallel (const Graphic3d_Vector& AV1, const Graphic3d_Vector& AV2) {
|
||||
|
||||
Standard_Real aDif1 = 0, aDif2 = 0, aDif3 = 0;
|
||||
|
||||
aDif1 = AV1.X () * AV2.Y () - AV1.Y () * AV2.X ();
|
||||
aDif2 = AV1.X () * AV2.Z () - AV1.Z () * AV2.X ();
|
||||
aDif3 = AV1.Y () * AV2.Z () - AV1.Z () * AV2.Y ();
|
||||
|
||||
return ( (Abs (aDif1) <= Graphic3d_Vector_MyEpsilon) &&
|
||||
(Abs (aDif2) <= Graphic3d_Vector_MyEpsilon) &&
|
||||
(Abs (aDif3) <= Graphic3d_Vector_MyEpsilon) );
|
||||
}
|
||||
|
||||
Standard_Real Graphic3d_Vector::NormeOf (const Standard_Real AX, const Standard_Real AY, const Standard_Real AZ) {
|
||||
|
||||
return (Sqrt (AX*AX+AY*AY+AZ*AZ));
|
||||
|
||||
}
|
||||
|
||||
Standard_Real Graphic3d_Vector::NormeOf (const Graphic3d_Vector& AVector) {
|
||||
|
||||
Standard_Real X, Y, Z;
|
||||
|
||||
AVector.Coord(X, Y, Z);
|
||||
return (Graphic3d_Vector::NormeOf (X, Y, Z));
|
||||
|
||||
}
|
120
src/Graphic3d/Graphic3d_Vector.hxx
Normal file
120
src/Graphic3d/Graphic3d_Vector.hxx
Normal file
@@ -0,0 +1,120 @@
|
||||
// Created by: NW,JPB,CAL
|
||||
// Copyright (c) 1991-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _Graphic3d_Vector_HeaderFile
|
||||
#define _Graphic3d_Vector_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
#include <Standard_ShortReal.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Graphic3d_Vertex.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
class Graphic3d_VectorError;
|
||||
|
||||
|
||||
//! This class allows the creation and update
|
||||
//! of a 3D vector.
|
||||
class Graphic3d_Vector
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
//! Creates a vector with 1.0, 0.0, 0.0 coordinates.
|
||||
Standard_EXPORT Graphic3d_Vector();
|
||||
|
||||
//! Creates a vector with <AX>, <AY>, <AZ> coordinates.
|
||||
Standard_EXPORT Graphic3d_Vector(const Standard_Real AX, const Standard_Real AY, const Standard_Real AZ);
|
||||
|
||||
//! Creates a vector from 2 points <APoint1> and <APoint2>.
|
||||
Standard_EXPORT Graphic3d_Vector(const Graphic3d_Vertex& APoint1, const Graphic3d_Vertex& APoint2);
|
||||
|
||||
//! Normalises <me>.
|
||||
//! Category: Methods to modify the class definition
|
||||
//! Warning: Raises VectorError if <me> is null.
|
||||
Standard_EXPORT void Normalize();
|
||||
|
||||
//! Modifies the coordinates of the vector <me>.
|
||||
Standard_EXPORT void SetCoord (const Standard_Real Xnew, const Standard_Real Ynew, const Standard_Real Znew);
|
||||
|
||||
//! Modifies the X coordinate of the vector <me>.
|
||||
Standard_EXPORT void SetXCoord (const Standard_Real Xnew);
|
||||
|
||||
//! Modifies the Y coordinate of the vector <me>.
|
||||
Standard_EXPORT void SetYCoord (const Standard_Real Ynew);
|
||||
|
||||
//! Modifies the Z coordinate of the vector <me>.
|
||||
Standard_EXPORT void SetZCoord (const Standard_Real Znew);
|
||||
|
||||
//! Returns the coordinates of the vector <me>.
|
||||
Standard_EXPORT void Coord (Standard_Real& AX, Standard_Real& AY, Standard_Real& AZ) const;
|
||||
|
||||
//! Returns Standard_True if <me> has length 1.
|
||||
Standard_EXPORT Standard_Boolean IsNormalized() const;
|
||||
|
||||
//! Returns Standard_True if <me> has length zero.
|
||||
Standard_EXPORT Standard_Boolean LengthZero() const;
|
||||
|
||||
//! Returns the X coordinates of the vector <me>.
|
||||
Standard_EXPORT Standard_Real X() const;
|
||||
|
||||
//! Returns the Y coordinate of the vector <me>.
|
||||
Standard_EXPORT Standard_Real Y() const;
|
||||
|
||||
//! Returns the Z coordinate of the vector <me>.
|
||||
Standard_EXPORT Standard_Real Z() const;
|
||||
|
||||
//! Returns Standard_True if the vector <AV1> and
|
||||
//! <AV2> are parallel.
|
||||
Standard_EXPORT static Standard_Boolean IsParallel (const Graphic3d_Vector& AV1, const Graphic3d_Vector& AV2);
|
||||
|
||||
//! Returns the norm of the vector <AX>, <AY>, <AZ>.
|
||||
Standard_EXPORT static Standard_Real NormeOf (const Standard_Real AX, const Standard_Real AY, const Standard_Real AZ);
|
||||
|
||||
//! Returns the norm of the vector <AVector>.
|
||||
Standard_EXPORT static Standard_Real NormeOf (const Graphic3d_Vector& AVector);
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
Standard_ShortReal MyX;
|
||||
Standard_ShortReal MyY;
|
||||
Standard_ShortReal MyZ;
|
||||
Standard_ShortReal MyNorme;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _Graphic3d_Vector_HeaderFile
|
37
src/Graphic3d/Graphic3d_VectorError.hxx
Normal file
37
src/Graphic3d/Graphic3d_VectorError.hxx
Normal file
@@ -0,0 +1,37 @@
|
||||
// Created on: 1993-03-31
|
||||
// Created by: NW,JPB,CAL
|
||||
// Copyright (c) 1993-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _Graphic3d_VectorError_HeaderFile
|
||||
#define _Graphic3d_VectorError_HeaderFile
|
||||
|
||||
#include <Standard_Type.hxx>
|
||||
#include <Standard_DefineException.hxx>
|
||||
#include <Standard_SStream.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
|
||||
class Graphic3d_VectorError;
|
||||
DEFINE_STANDARD_HANDLE(Graphic3d_VectorError, Standard_OutOfRange)
|
||||
|
||||
#if !defined No_Exception && !defined No_Graphic3d_VectorError
|
||||
#define Graphic3d_VectorError_Raise_if(CONDITION, MESSAGE) \
|
||||
if (CONDITION) throw Graphic3d_VectorError(MESSAGE);
|
||||
#else
|
||||
#define Graphic3d_VectorError_Raise_if(CONDITION, MESSAGE)
|
||||
#endif
|
||||
|
||||
DEFINE_STANDARD_EXCEPTION(Graphic3d_VectorError, Standard_OutOfRange)
|
||||
|
||||
#endif // _Graphic3d_VectorError_HeaderFile
|
@@ -33,14 +33,11 @@ struct Graphic3d_ZLayerSettings
|
||||
|
||||
//! Default settings.
|
||||
Graphic3d_ZLayerSettings()
|
||||
: myCullingDistance (Precision::Infinite()),
|
||||
myCullingSize (Precision::Infinite()),
|
||||
myIsImmediate (Standard_False),
|
||||
: myIsImmediate (Standard_False),
|
||||
myUseEnvironmentTexture (Standard_True),
|
||||
myToEnableDepthTest (Standard_True),
|
||||
myToEnableDepthWrite(Standard_True),
|
||||
myToClearDepth (Standard_True),
|
||||
myToRenderInDepthPrepass (Standard_True) {}
|
||||
myToClearDepth (Standard_True) {}
|
||||
|
||||
//! Return user-provided name.
|
||||
const TCollection_AsciiString& Name() const { return myName; }
|
||||
@@ -65,30 +62,6 @@ 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; }
|
||||
|
||||
@@ -119,12 +92,6 @@ 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; }
|
||||
|
||||
@@ -195,15 +162,12 @@ 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
|
||||
|
||||
};
|
||||
|
||||
|
@@ -32,6 +32,7 @@ namespace
|
||||
{
|
||||
Standard_Byte v[3];
|
||||
typedef Standard_Byte ComponentType_t; //!< Component type
|
||||
static Standard_Integer Length() { return 3; } //!< Returns the number of components
|
||||
};
|
||||
|
||||
static Image_ColorXXX24 operator- (const Image_ColorXXX24& theA,
|
||||
|
@@ -6,6 +6,7 @@ IntCurve_IntConicConic.cxx
|
||||
IntCurve_IntConicConic.hxx
|
||||
IntCurve_IntConicConic.lxx
|
||||
IntCurve_IntConicConic_1.cxx
|
||||
IntCurve_IntConicConic_1.hxx
|
||||
IntCurve_IntConicConic_Tool.cxx
|
||||
IntCurve_IntConicConic_Tool.hxx
|
||||
IntCurve_IntConicCurveGen.gxx
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include <IntAna2d_IntPoint.hxx>
|
||||
#include <IntCurve_IConicTool.hxx>
|
||||
#include <IntCurve_IntConicConic.hxx>
|
||||
#include <IntCurve_IntConicConic_1.hxx>
|
||||
#include <IntCurve_PConic.hxx>
|
||||
#include <IntRes2d_Domain.hxx>
|
||||
#include <Precision.hxx>
|
||||
@@ -36,6 +37,7 @@
|
||||
//=======================================================================
|
||||
// Perform() for
|
||||
// Line - Parabola
|
||||
// Line - Elipse
|
||||
// Line - Hyperbola
|
||||
// Circle - Parabola
|
||||
// Circle - Elipse
|
||||
@@ -188,6 +190,34 @@ void IntCurve_IntConicConic::Perform(const gp_Lin2d& L,
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose : Line - Elipse
|
||||
//=======================================================================
|
||||
void IntCurve_IntConicConic::Perform(const gp_Lin2d& L,
|
||||
const IntRes2d_Domain& DL,
|
||||
const gp_Elips2d& E,
|
||||
const IntRes2d_Domain& DE,
|
||||
const Standard_Real TolConf,
|
||||
const Standard_Real Tol)
|
||||
{
|
||||
|
||||
this->ResetFields();
|
||||
IntCurve_IConicTool ITool(L);
|
||||
IntCurve_PConic PCurve(E);
|
||||
PCurve.SetAccuracy(20);
|
||||
|
||||
Inter.SetReversedParameters(ReversedParameters());
|
||||
if(! DE.IsClosed()) {
|
||||
IntRes2d_Domain D(DE);
|
||||
D.SetEquivalentParameters(DE.FirstParameter(),DE.FirstParameter()+M_PI+M_PI);
|
||||
Inter.Perform(ITool,DL,PCurve,D,TolConf,Tol);
|
||||
}
|
||||
else {
|
||||
Inter.Perform(ITool,DL,PCurve,DE,TolConf,Tol);
|
||||
}
|
||||
this->SetValues(Inter);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <IntCurve_IConicTool.hxx>
|
||||
#include <IntCurve_IntConicConic.hxx>
|
||||
#include <IntCurve_IntConicConic_1.hxx>
|
||||
#include <IntCurve_IntConicConic_Tool.hxx>
|
||||
#include <IntCurve_PConic.hxx>
|
||||
#include <IntImpParGen.hxx>
|
||||
@@ -36,7 +37,6 @@
|
||||
#include <IntRes2d_TypeTrans.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard_ConstructionError.hxx>
|
||||
#include <Extrema_ExtElC2d.hxx>
|
||||
|
||||
Standard_Boolean Affichage=Standard_False;
|
||||
Standard_Boolean AffichageGraph=Standard_True;
|
||||
@@ -2245,476 +2245,3 @@ const IntRes2d_IntersectionPoint SegmentToPoint( const IntRes2d_IntersectionPoin
|
||||
}
|
||||
return(IntRes2d_IntersectionPoint(Pa.Value(),u1,u2,t1,t2,Standard_False));
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : LineEllipseGeometricIntersection
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void LineEllipseGeometricIntersection(const gp_Lin2d& Line,
|
||||
const gp_Elips2d& Ellipse,
|
||||
const Standard_Real ,
|
||||
const Standard_Real TolTang,
|
||||
PeriodicInterval& EInt1,
|
||||
PeriodicInterval& EInt2,
|
||||
Standard_Integer& nbsol)
|
||||
{
|
||||
|
||||
const gp_Ax22d& anElAxis = Ellipse.Axis();
|
||||
gp_Trsf2d aTr;
|
||||
aTr.SetTransformation(anElAxis.XAxis());
|
||||
gp_Elips2d aTEllipse = Ellipse.Transformed(aTr);
|
||||
gp_Lin2d aTLine = Line.Transformed(aTr);
|
||||
Standard_Real aDY = aTLine.Position().Direction().Y();
|
||||
Standard_Boolean IsVert = Abs(aDY) > 1. - 2. * Epsilon(1.);
|
||||
//
|
||||
Standard_Real a = aTEllipse.MajorRadius();
|
||||
Standard_Real b = aTEllipse.MinorRadius();
|
||||
Standard_Real a2 = a * a;
|
||||
Standard_Real b2 = b * b;
|
||||
//
|
||||
Standard_Real eps0 = 1.e-12;
|
||||
if (b / a < 1.e-5)
|
||||
{
|
||||
eps0 = 1.e-6;
|
||||
}
|
||||
//
|
||||
Standard_Real anA, aB, aC;
|
||||
aTLine.Coefficients(anA, aB, aC);
|
||||
if (IsVert)
|
||||
{
|
||||
aC += aB * aTLine.Position().Location().Y();
|
||||
aB = 0.;
|
||||
}
|
||||
//
|
||||
Standard_Real x1 = 0., y1 = 0., x2 = 0., y2 = 0.;
|
||||
if (Abs(aB) > eps0 )
|
||||
{
|
||||
Standard_Real m = -anA / aB;
|
||||
Standard_Real m2 = m * m;
|
||||
Standard_Real c = -aC / aB;
|
||||
Standard_Real c2 = c * c;
|
||||
Standard_Real D = a2 * m2 + b2 - c2;
|
||||
if (D < 0.)
|
||||
{
|
||||
Extrema_ExtElC2d anExt(aTLine, aTEllipse);
|
||||
Standard_Integer i, imin = 0;
|
||||
Standard_Real dmin = RealLast();
|
||||
for (i = 1; i <= anExt.NbExt(); ++i)
|
||||
{
|
||||
if (anExt.SquareDistance(i) < dmin)
|
||||
{
|
||||
dmin = anExt.SquareDistance(i);
|
||||
imin = i;
|
||||
}
|
||||
}
|
||||
if (imin > 0 && dmin <= TolTang * TolTang)
|
||||
{
|
||||
nbsol = 1;
|
||||
Extrema_POnCurv2d aP1, aP2;
|
||||
anExt.Points(imin, aP1, aP2);
|
||||
Standard_Real pe1 = aP2.Parameter();
|
||||
EInt1.SetValues(pe1, pe1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nbsol = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
D = Sqrt(D);
|
||||
Standard_Real n = a2 * m2 + b2;
|
||||
Standard_Real k = a * b * D / n;
|
||||
Standard_Real l = -a2 * m * c / n;
|
||||
x1 = l + k;
|
||||
y1 = m * x1 + c;
|
||||
x2 = l - k;
|
||||
y2 = m * x2 + c;
|
||||
nbsol = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = -aC / anA;
|
||||
if (Abs(x1) > a + TolTang)
|
||||
{
|
||||
nbsol = 0;
|
||||
return;
|
||||
}
|
||||
else if (Abs(x1) >= a - Epsilon(1. + a))
|
||||
{
|
||||
nbsol = 1;
|
||||
y1 = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
y1 = b * Sqrt(1. - x1 * x1 / a2);
|
||||
x2 = x1;
|
||||
y2 = -y1;
|
||||
nbsol = 2;
|
||||
}
|
||||
}
|
||||
|
||||
gp_Pnt2d aP1(x1, y1);
|
||||
gp_Pnt2d aP2(x2, y2);
|
||||
Standard_Real pe1 = 0., pe2 = 0.;
|
||||
pe1 = ElCLib::Parameter(aTEllipse, aP1);
|
||||
if (nbsol > 1)
|
||||
{
|
||||
pe2 = ElCLib::Parameter(aTEllipse, aP2);
|
||||
if (pe2 < pe1)
|
||||
{
|
||||
Standard_Real t = pe1;
|
||||
pe1 = pe2;
|
||||
pe2 = t;
|
||||
}
|
||||
EInt2.SetValues(pe2, pe2);
|
||||
}
|
||||
EInt1.SetValues(pe1, pe1);
|
||||
|
||||
|
||||
}
|
||||
//=======================================================================
|
||||
//function : ProjectOnLAndIntersectWithLDomain
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void ProjectOnLAndIntersectWithLDomain(const gp_Elips2d& Ellipse
|
||||
, const gp_Lin2d& Line
|
||||
, PeriodicInterval& EDomainAndRes
|
||||
, Interval& LDomain
|
||||
, PeriodicInterval* EllipseSolution
|
||||
, Interval* LineSolution
|
||||
, Standard_Integer &NbSolTotal
|
||||
, const IntRes2d_Domain& RefLineDomain
|
||||
, const IntRes2d_Domain&)
|
||||
{
|
||||
|
||||
if (EDomainAndRes.IsNull()) return;
|
||||
//-------------------------------------------------------------------------
|
||||
//-- On cherche l intervalle correspondant sur C2
|
||||
//-- Puis on intersecte l intervalle avec le domaine de C2
|
||||
//-- Enfin, on cherche l intervalle correspondant sur C1
|
||||
//--
|
||||
|
||||
Standard_Real Linf = ElCLib::Parameter(Line
|
||||
, ElCLib::Value(EDomainAndRes.Binf, Ellipse));
|
||||
Standard_Real Lsup = ElCLib::Parameter(Line
|
||||
, ElCLib::Value(EDomainAndRes.Bsup, Ellipse));
|
||||
|
||||
Interval LInter(Linf, Lsup); //-- Necessairement Borne
|
||||
|
||||
Interval LInterAndDomain = LDomain.IntersectionWithBounded(LInter);
|
||||
|
||||
if (!LInterAndDomain.IsNull) {
|
||||
|
||||
Standard_Real DomLinf = (RefLineDomain.HasFirstPoint()) ? RefLineDomain.FirstParameter() : -Precision::Infinite();
|
||||
Standard_Real DomLsup = (RefLineDomain.HasLastPoint()) ? RefLineDomain.LastParameter() : Precision::Infinite();
|
||||
|
||||
Linf = LInterAndDomain.Binf;
|
||||
Lsup = LInterAndDomain.Bsup;
|
||||
|
||||
if (Linf<DomLinf) {
|
||||
Linf = DomLinf;
|
||||
}
|
||||
if (Lsup<DomLinf) {
|
||||
Lsup = DomLinf;
|
||||
}
|
||||
|
||||
if (Linf>DomLsup) {
|
||||
Linf = DomLsup;
|
||||
}
|
||||
if (Lsup>DomLsup) {
|
||||
Lsup = DomLsup;
|
||||
}
|
||||
|
||||
LInterAndDomain.Binf = Linf;
|
||||
LInterAndDomain.Bsup = Lsup;
|
||||
|
||||
|
||||
Standard_Real Einf = EDomainAndRes.Binf;
|
||||
Standard_Real Esup = EDomainAndRes.Bsup;
|
||||
|
||||
if (Einf >= Esup) { Einf = EDomainAndRes.Binf; Esup = EDomainAndRes.Bsup; }
|
||||
EllipseSolution[NbSolTotal] = PeriodicInterval(Einf, Esup);
|
||||
if (EllipseSolution[NbSolTotal].Length() > M_PI)
|
||||
EllipseSolution[NbSolTotal].Complement();
|
||||
|
||||
LineSolution[NbSolTotal] = LInterAndDomain;
|
||||
NbSolTotal++;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose : Line - Elipse
|
||||
//=======================================================================
|
||||
void IntCurve_IntConicConic::Perform(const gp_Lin2d& L, const
|
||||
IntRes2d_Domain& DL, const gp_Elips2d& E,
|
||||
const IntRes2d_Domain& DE, const Standard_Real TolConf,
|
||||
const Standard_Real Tol)
|
||||
{
|
||||
Standard_Boolean TheReversedParameters = ReversedParameters();
|
||||
this->ResetFields();
|
||||
this->SetReversedParameters(TheReversedParameters);
|
||||
|
||||
Standard_Integer nbsol = 0;
|
||||
PeriodicInterval EInt1, EInt2;
|
||||
|
||||
LineEllipseGeometricIntersection(L, E, TolConf, Tol, EInt1, EInt2, nbsol);
|
||||
done = Standard_True;
|
||||
if (nbsol == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//
|
||||
if (nbsol == 2 && EInt2.Bsup == EInt1.Binf + PIpPI) {
|
||||
Standard_Real FirstBound = DE.FirstParameter();
|
||||
Standard_Real LastBound = DE.LastParameter();
|
||||
Standard_Real FirstTol = DE.FirstTolerance();
|
||||
Standard_Real LastTol = DE.LastTolerance();
|
||||
if (EInt1.Binf == 0 && FirstBound - FirstTol > EInt1.Bsup)
|
||||
{
|
||||
nbsol = 1;
|
||||
EInt1.SetValues(EInt2.Binf, EInt2.Bsup);
|
||||
}
|
||||
else if (EInt2.Bsup == PIpPI && LastBound + LastTol < EInt2.Binf)
|
||||
{
|
||||
nbsol = 1;
|
||||
}
|
||||
}
|
||||
//
|
||||
PeriodicInterval EDomain(DE);
|
||||
Standard_Real deltat = EDomain.Bsup - EDomain.Binf;
|
||||
while (EDomain.Binf >= PIpPI) EDomain.Binf -= PIpPI;
|
||||
while (EDomain.Binf < 0.0) EDomain.Binf += PIpPI;
|
||||
EDomain.Bsup = EDomain.Binf + deltat;
|
||||
//
|
||||
Standard_Real BinfModif = EDomain.Binf;
|
||||
Standard_Real BsupModif = EDomain.Bsup;
|
||||
BinfModif -= DE.FirstTolerance() / E.MinorRadius();
|
||||
BsupModif += DE.LastTolerance() / E.MinorRadius();
|
||||
deltat = BsupModif - BinfModif;
|
||||
if (deltat <= PIpPI) {
|
||||
EDomain.Binf = BinfModif;
|
||||
EDomain.Bsup = BsupModif;
|
||||
}
|
||||
else {
|
||||
Standard_Real t = PIpPI - deltat;
|
||||
t *= 0.5;
|
||||
EDomain.Binf = BinfModif + t;
|
||||
EDomain.Bsup = BsupModif - t;
|
||||
}
|
||||
deltat = EDomain.Bsup - EDomain.Binf;
|
||||
while (EDomain.Binf >= PIpPI) EDomain.Binf -= PIpPI;
|
||||
while (EDomain.Binf < 0.0) EDomain.Binf += PIpPI;
|
||||
EDomain.Bsup = EDomain.Binf + deltat;
|
||||
//
|
||||
Interval LDomain(DL);
|
||||
|
||||
Standard_Integer NbSolTotal = 0;
|
||||
|
||||
PeriodicInterval SolutionEllipse[4];
|
||||
Interval SolutionLine[4];
|
||||
//----------------------------------------------------------------------
|
||||
//----------- Treatment of first geometric interval EInt1 ----
|
||||
//----------------------------------------------------------------------
|
||||
PeriodicInterval EDomainAndRes = EDomain.FirstIntersection(EInt1);
|
||||
|
||||
ProjectOnLAndIntersectWithLDomain(E, L, EDomainAndRes, LDomain, SolutionEllipse
|
||||
, SolutionLine, NbSolTotal, DL, DE);
|
||||
|
||||
EDomainAndRes = EDomain.SecondIntersection(EInt1);
|
||||
|
||||
ProjectOnLAndIntersectWithLDomain(E, L, EDomainAndRes, LDomain, SolutionEllipse
|
||||
, SolutionLine, NbSolTotal, DL, DE);
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//----------- Treatment of second geometric interval EInt2 ----
|
||||
//----------------------------------------------------------------------
|
||||
if (nbsol == 2)
|
||||
{
|
||||
EDomainAndRes = EDomain.FirstIntersection(EInt2);
|
||||
|
||||
ProjectOnLAndIntersectWithLDomain(E, L, EDomainAndRes, LDomain, SolutionEllipse
|
||||
, SolutionLine, NbSolTotal, DL, DE);
|
||||
|
||||
EDomainAndRes = EDomain.SecondIntersection(EInt2);
|
||||
|
||||
ProjectOnLAndIntersectWithLDomain(E, L, EDomainAndRes, LDomain, SolutionEllipse
|
||||
, SolutionLine, NbSolTotal, DL, DE);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//-- Calculation of Transitions at Positions.
|
||||
//----------------------------------------------------------------------
|
||||
Standard_Real R = E.MinorRadius();
|
||||
Standard_Integer i;
|
||||
Standard_Real MaxTol = TolConf;
|
||||
if (MaxTol<Tol) MaxTol = Tol;
|
||||
if (MaxTol<1.0e-10) MaxTol = 1.0e-10;
|
||||
|
||||
for (i = 0; i<NbSolTotal; i++) {
|
||||
if ((R * SolutionEllipse[i].Length())<MaxTol
|
||||
&& (SolutionLine[i].Length())<MaxTol) {
|
||||
|
||||
Standard_Real t = (SolutionEllipse[i].Binf + SolutionEllipse[i].Bsup)*0.5;
|
||||
SolutionEllipse[i].Binf = SolutionEllipse[i].Bsup = t;
|
||||
|
||||
t = (SolutionLine[i].Binf + SolutionLine[i].Bsup)*0.5;
|
||||
SolutionLine[i].Binf = SolutionLine[i].Bsup = t;
|
||||
}
|
||||
}
|
||||
//
|
||||
if (NbSolTotal) {
|
||||
gp_Ax22d EllipseAxis = E.Axis();
|
||||
gp_Ax2d LineAxis = L.Position();
|
||||
gp_Pnt2d P1a, P2a, P1b, P2b;
|
||||
gp_Vec2d Tan1, Tan2, Norm1;
|
||||
gp_Vec2d Norm2(0.0, 0.0);
|
||||
IntRes2d_Transition T1a, T2a, T1b, T2b;
|
||||
IntRes2d_Position Pos1a, Pos1b, Pos2a, Pos2b;
|
||||
|
||||
ElCLib::EllipseD1(SolutionEllipse[0].Binf, EllipseAxis, E.MajorRadius(), E.MinorRadius(), P1a, Tan1);
|
||||
ElCLib::LineD1(SolutionLine[0].Binf, LineAxis, P2a, Tan2);
|
||||
|
||||
Standard_Boolean isOpposite = (Tan1.Dot(Tan2) < 0.0);
|
||||
for (i = 0; i<NbSolTotal; i++)
|
||||
{
|
||||
Standard_Real p1 = SolutionEllipse[i].Binf;
|
||||
Standard_Real p2 = SolutionEllipse[i].Bsup;
|
||||
Standard_Real q1 = DE.FirstParameter();
|
||||
Standard_Real q2 = DE.LastParameter();
|
||||
|
||||
if (p1>q2) {
|
||||
do {
|
||||
p1 -= PIpPI;
|
||||
p2 -= PIpPI;
|
||||
} while ((p1>q2));
|
||||
}
|
||||
else if (p2<q1) {
|
||||
do {
|
||||
p1 += PIpPI;
|
||||
p2 += PIpPI;
|
||||
} while ((p2<q1));
|
||||
}
|
||||
if (p1<q1 && p2>q1) {
|
||||
p1 = q1;
|
||||
}
|
||||
if (p1<q2 && p2>q2) {
|
||||
p2 = q2;
|
||||
}
|
||||
|
||||
SolutionEllipse[i].Binf = p1;
|
||||
SolutionEllipse[i].Bsup = p2;
|
||||
|
||||
Standard_Real Linf = isOpposite ? SolutionLine[i].Bsup : SolutionLine[i].Binf;
|
||||
Standard_Real Lsup = isOpposite ? SolutionLine[i].Binf : SolutionLine[i].Bsup;
|
||||
|
||||
if (Linf > Lsup) {
|
||||
Standard_Real T = SolutionEllipse[i].Binf;
|
||||
SolutionEllipse[i].Binf = SolutionEllipse[i].Bsup;
|
||||
SolutionEllipse[i].Bsup = T;
|
||||
T = Linf; Linf = Lsup; Lsup = T;
|
||||
}
|
||||
|
||||
|
||||
ElCLib::EllipseD2(SolutionEllipse[i].Binf, EllipseAxis, E.MajorRadius(),
|
||||
E.MinorRadius(), P1a, Tan1, Norm1);
|
||||
ElCLib::LineD1(Linf, LineAxis, P2a, Tan2);
|
||||
|
||||
IntImpParGen::DeterminePosition(Pos1a, DE, P1a, SolutionEllipse[i].Binf);
|
||||
IntImpParGen::DeterminePosition(Pos2a, DL, P2a, Linf);
|
||||
Determine_Transition_LC(Pos1a, Tan1, Norm1, T1a, Pos2a, Tan2, Norm2, T2a, Tol);
|
||||
Standard_Real Einf;
|
||||
if (Pos1a == IntRes2d_End) {
|
||||
Einf = DE.LastParameter();
|
||||
P1a = DE.LastPoint();
|
||||
Linf = ElCLib::Parameter(L, P1a);
|
||||
|
||||
ElCLib::EllipseD2(Einf, EllipseAxis, E.MajorRadius(),
|
||||
E.MinorRadius(), P1a, Tan1, Norm1);
|
||||
ElCLib::LineD1(Linf, LineAxis, P2a, Tan2);
|
||||
IntImpParGen::DeterminePosition(Pos1a, DE, P1a, Einf);
|
||||
IntImpParGen::DeterminePosition(Pos2a, DL, P2a, Linf);
|
||||
Determine_Transition_LC(Pos1a, Tan1, Norm1, T1a, Pos2a, Tan2, Norm2, T2a, Tol);
|
||||
}
|
||||
else if (Pos1a == IntRes2d_Head) {
|
||||
Einf = DE.FirstParameter();
|
||||
P1a = DE.FirstPoint();
|
||||
Linf = ElCLib::Parameter(L, P1a);
|
||||
|
||||
ElCLib::EllipseD2(Einf, EllipseAxis, E.MajorRadius(),
|
||||
E.MinorRadius(), P1a, Tan1, Norm1);
|
||||
ElCLib::LineD1(Linf, LineAxis, P2a, Tan2);
|
||||
IntImpParGen::DeterminePosition(Pos1a, DE, P1a, Einf);
|
||||
IntImpParGen::DeterminePosition(Pos2a, DL, P2a, Linf);
|
||||
Determine_Transition_LC(Pos1a, Tan1, Norm1, T1a, Pos2a, Tan2, Norm2, T2a, Tol);
|
||||
}
|
||||
else {
|
||||
Einf = NormalizeOnCircleDomain(SolutionEllipse[i].Binf, DE);
|
||||
}
|
||||
|
||||
IntRes2d_IntersectionPoint NewPoint1(P1a, Linf, Einf, T2a, T1a, ReversedParameters());
|
||||
|
||||
if ((SolutionLine[i].Length() + SolutionEllipse[i].Length()) >0.0) {
|
||||
|
||||
ElCLib::EllipseD2(SolutionEllipse[i].Binf, EllipseAxis, E.MajorRadius(),
|
||||
E.MinorRadius(), P1b, Tan1, Norm1);
|
||||
ElCLib::LineD1(Lsup, LineAxis, P2b, Tan2);
|
||||
|
||||
IntImpParGen::DeterminePosition(Pos1b, DE, P1b, SolutionEllipse[i].Bsup);
|
||||
IntImpParGen::DeterminePosition(Pos2b, DL, P2b, Lsup);
|
||||
Determine_Transition_LC(Pos1b, Tan1, Norm1, T1b, Pos2b, Tan2, Norm2, T2b, Tol);
|
||||
Standard_Real Esup;
|
||||
if (Pos1b == IntRes2d_End) {
|
||||
Esup = DL.LastParameter();
|
||||
P1b = DE.LastPoint();
|
||||
Lsup = ElCLib::Parameter(L, P1b);
|
||||
ElCLib::EllipseD2(Esup, EllipseAxis, E.MajorRadius(),
|
||||
E.MinorRadius(), P1b, Tan1, Norm1);
|
||||
ElCLib::LineD1(Lsup, LineAxis, P2b, Tan2);
|
||||
|
||||
IntImpParGen::DeterminePosition(Pos1b, DE, P1b, Esup);
|
||||
IntImpParGen::DeterminePosition(Pos2b, DL, P2b, Lsup);
|
||||
Determine_Transition_LC(Pos1b, Tan1, Norm1, T1b, Pos2b, Tan2, Norm2, T2b, Tol);
|
||||
}
|
||||
else if (Pos1b == IntRes2d_Head) {
|
||||
Esup = DE.FirstParameter();
|
||||
P1b = DE.FirstPoint();
|
||||
Lsup = ElCLib::Parameter(L, P1b);
|
||||
ElCLib::EllipseD2(Esup, EllipseAxis, E.MajorRadius(),
|
||||
E.MinorRadius(), P1b, Tan1, Norm1);
|
||||
ElCLib::LineD1(Lsup, LineAxis, P2b, Tan2);
|
||||
|
||||
IntImpParGen::DeterminePosition(Pos1b, DE, P1b, Esup);
|
||||
IntImpParGen::DeterminePosition(Pos2b, DL, P2b, Lsup);
|
||||
Determine_Transition_LC(Pos1b, Tan1, Norm1, T1b, Pos2b, Tan2, Norm2, T2b, Tol);
|
||||
}
|
||||
else {
|
||||
Esup = NormalizeOnCircleDomain(SolutionEllipse[i].Bsup, DE);
|
||||
}
|
||||
|
||||
IntRes2d_IntersectionPoint NewPoint2(P1b, Lsup, Esup, T2b, T1b, ReversedParameters());
|
||||
|
||||
if (((Abs(Esup - Einf)*R > MaxTol) && (Abs(Lsup - Linf) > MaxTol))
|
||||
|| (T1a.TransitionType() != T2a.TransitionType())) {
|
||||
IntRes2d_IntersectionSegment NewSeg(NewPoint1, NewPoint2, isOpposite, ReversedParameters());
|
||||
Append(NewSeg);
|
||||
}
|
||||
else {
|
||||
if (Pos1a != IntRes2d_Middle || Pos2a != IntRes2d_Middle) {
|
||||
Insert(NewPoint1);
|
||||
}
|
||||
if (Pos1b != IntRes2d_Middle || Pos2b != IntRes2d_Middle) {
|
||||
Insert(NewPoint2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Insert(NewPoint1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
92
src/IntCurve/IntCurve_IntConicConic_1.hxx
Normal file
92
src/IntCurve/IntCurve_IntConicConic_1.hxx
Normal file
@@ -0,0 +1,92 @@
|
||||
// Created on: 1992-05-06
|
||||
// Created by: Laurent BUCHARD
|
||||
// Copyright (c) 1992-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef IntCurve_IntConicConic_1_HeaderFile
|
||||
#define IntCurve_IntConicConic_1_HeaderFile
|
||||
|
||||
#include <IntCurve_IntConicConic_Tool.hxx>
|
||||
|
||||
|
||||
//======================================================================
|
||||
//=== I n t e r s e c t i o n C e r c l e C e r c l e =====
|
||||
//======================================================================
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void CircleCircleGeometricIntersection(const gp_Circ2d& C1
|
||||
,const gp_Circ2d& C2
|
||||
,const Standard_Real Tol
|
||||
,PeriodicInterval& C1_Res1
|
||||
,PeriodicInterval& C1_Res2
|
||||
,Standard_Integer& nbsol);
|
||||
//----------------------------------------------------------------------
|
||||
void CircleCircleDomainIntersection(const gp_Circ2d& C1
|
||||
,const gp_Circ2d& C2
|
||||
,const Standard_Real Tol
|
||||
,PeriodicInterval& Res1
|
||||
,PeriodicInterval& C1_Res2
|
||||
,Standard_Integer& nbsol);
|
||||
//----------------------------------------------------------------------
|
||||
void ProjectOnC2AndIntersectWithC2Domain(const gp_Circ2d& Circle1
|
||||
,const gp_Circ2d& Circle2
|
||||
,PeriodicInterval& C1DomainAndRes
|
||||
,PeriodicInterval& C2Domain
|
||||
,PeriodicInterval* SolutionC1
|
||||
,PeriodicInterval* SolutionC2
|
||||
,Standard_Integer &NbSolTotal
|
||||
,const Standard_Boolean IdentCircles);
|
||||
|
||||
|
||||
|
||||
//======================================================================
|
||||
//=== I n t e r s e c t i o n L i g n e C e r c l e =====
|
||||
//======================================================================
|
||||
void LineCircleGeometricIntersection(const gp_Lin2d& Line
|
||||
,const gp_Circ2d& Circle
|
||||
,const Standard_Real Tol
|
||||
,PeriodicInterval& C1Int
|
||||
,PeriodicInterval& C2Int
|
||||
,Standard_Integer& nbsol);
|
||||
|
||||
|
||||
void ProjectOnLAndIntersectWithLDomain(const gp_Circ2d& Circle
|
||||
,const gp_Lin2d& Line
|
||||
,PeriodicInterval& CDomainAndRes
|
||||
,Interval& LDomain
|
||||
,PeriodicInterval* CircleSolution
|
||||
,Interval* LineSolution
|
||||
,Standard_Integer &NbSolTotal);
|
||||
|
||||
|
||||
//======================================================================
|
||||
//=== I n t e r s e c t i o n L i g n e L i g n e =====
|
||||
//======================================================================
|
||||
|
||||
void DomainIntersection(const IntRes2d_Domain& Domain
|
||||
,const Standard_Real U1inf
|
||||
,const Standard_Real U1sup
|
||||
,Standard_Real& Res1inf
|
||||
,Standard_Real& Res1sup);
|
||||
|
||||
void LineLineGeometricIntersection(const gp_Lin2d& L1
|
||||
,const gp_Lin2d& L2
|
||||
,const Standard_Real Tol
|
||||
,Standard_Real& U1
|
||||
,Standard_Real& U2
|
||||
,Standard_Real& SinDemiAngle
|
||||
,Standard_Integer& nbsol);
|
||||
|
||||
|
||||
#endif
|
@@ -222,11 +222,7 @@ Standard_Boolean IntTools_EdgeFace::IsCoincident()
|
||||
//
|
||||
GeomAPI_ProjectPointOnSurf& aProjector=myContext->ProjPS(myFace);
|
||||
|
||||
Standard_Integer aNbSeg=23;
|
||||
if (myC.GetType() == GeomAbs_Line &&
|
||||
myS.GetType() == GeomAbs_Plane)
|
||||
aNbSeg = 2; // Check only three points for Line/Plane intersection
|
||||
|
||||
const Standard_Integer aNbSeg=23;
|
||||
const Standard_Real aTresh=0.5;
|
||||
const Standard_Integer aTreshIdxF = RealToInt((aNbSeg+1)*0.25),
|
||||
aTreshIdxL = RealToInt((aNbSeg+1)*0.75);
|
||||
|
@@ -155,7 +155,6 @@ public:
|
||||
// ---------- PUBLIC METHODS ------------
|
||||
|
||||
//! Empty constructor; should be used with caution.
|
||||
//! @sa methods Resize() and Move().
|
||||
NCollection_Array1()
|
||||
: myLowerBound (1),
|
||||
myUpperBound (0),
|
||||
@@ -189,36 +188,25 @@ public:
|
||||
Standard_OutOfMemory_Raise_if (!pBegin, "NCollection_Array1 : Allocation failed");
|
||||
myData = pBegin - myLowerBound;
|
||||
|
||||
Assign (theOther);
|
||||
*this = theOther;
|
||||
}
|
||||
|
||||
#ifndef OCCT_NO_RVALUE_REFERENCE
|
||||
//! Move constructor
|
||||
#if(defined(_MSC_VER) && (_MSC_VER < 1600))
|
||||
#else
|
||||
NCollection_Array1 (NCollection_Array1&& theOther)
|
||||
: myLowerBound (theOther.myLowerBound),
|
||||
myUpperBound (theOther.myUpperBound),
|
||||
myDeletable (theOther.myDeletable),
|
||||
myData (theOther.myData)
|
||||
{
|
||||
theOther.myUpperBound = theOther.myLowerBound - 1;
|
||||
theOther.myDeletable = false;
|
||||
theOther.myData = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//! C array-based constructor.
|
||||
//!
|
||||
//! Makes this array to use the buffer pointed by theBegin
|
||||
//! instead of allocating it dynamically.
|
||||
//! Argument theBegin should be a reference to the first element
|
||||
//! of the pre-allocated buffer (usually local C array buffer),
|
||||
//! with size at least theUpper - theLower + 1 items.
|
||||
//!
|
||||
//! Warning: returning array object created using this constructor
|
||||
//! from function by value will result in undefined behavior
|
||||
//! if compiler performs return value optimization (this is likely
|
||||
//! to be true for all modern compilers in release mode).
|
||||
//! The same happens if array is copied using Move() function
|
||||
//! or move constructor and target object's lifespan is longer
|
||||
//! than that of the buffer.
|
||||
//! C array-based constructor
|
||||
NCollection_Array1 (const TheItemType& theBegin,
|
||||
const Standard_Integer theLower,
|
||||
const Standard_Integer theUpper) :
|
||||
@@ -274,9 +262,7 @@ public:
|
||||
Standard_Boolean IsAllocated (void) const
|
||||
{ return myDeletable; }
|
||||
|
||||
//! Copies data of theOther array to this.
|
||||
//! This array should be pre-allocated and have the same length as theOther;
|
||||
//! otherwise exception Standard_DimensionMismatch is thrown.
|
||||
//! Assignment
|
||||
NCollection_Array1& Assign (const NCollection_Array1& theOther)
|
||||
{
|
||||
if (&theOther == this)
|
||||
@@ -295,10 +281,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Move assignment.
|
||||
//! This array will borrow all the data from theOther.
|
||||
//! The moved object will keep pointer to the memory buffer and
|
||||
//! range, but it will not free the buffer on destruction.
|
||||
//! Move assignment
|
||||
NCollection_Array1& Move (NCollection_Array1& theOther)
|
||||
{
|
||||
if (&theOther == this)
|
||||
@@ -310,25 +293,26 @@ public:
|
||||
{
|
||||
delete[] &myData[myLowerBound];
|
||||
}
|
||||
|
||||
myLowerBound = theOther.myLowerBound;
|
||||
myUpperBound = theOther.myUpperBound;
|
||||
myDeletable = theOther.myDeletable;
|
||||
myData = theOther.myData;
|
||||
|
||||
theOther.myUpperBound = theOther.myLowerBound - 1;
|
||||
theOther.myDeletable = Standard_False;
|
||||
|
||||
theOther.myData = NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Assignment operator; @sa Assign()
|
||||
//! Assignment operator
|
||||
NCollection_Array1& operator= (const NCollection_Array1& theOther)
|
||||
{
|
||||
return Assign (theOther);
|
||||
}
|
||||
|
||||
#ifndef OCCT_NO_RVALUE_REFERENCE
|
||||
//! Move assignment operator; @sa Move()
|
||||
//! Move assignment operator.
|
||||
#if(defined(_MSC_VER) && (_MSC_VER < 1600))
|
||||
#else
|
||||
NCollection_Array1& operator= (NCollection_Array1&& theOther)
|
||||
{
|
||||
return Move (theOther);
|
||||
@@ -440,10 +424,7 @@ public:
|
||||
|
||||
//! Destructor - releases the memory
|
||||
~NCollection_Array1 (void)
|
||||
{
|
||||
if (myDeletable)
|
||||
delete [] &(myData[myLowerBound]);
|
||||
}
|
||||
{ if (myDeletable) delete [] &(myData[myLowerBound]); }
|
||||
|
||||
protected:
|
||||
// ---------- PROTECTED FIELDS -----------
|
||||
|
@@ -29,6 +29,7 @@ Standard_Boolean NCollection_BaseMap::BeginResize
|
||||
NCollection_ListNode**& data1,
|
||||
NCollection_ListNode**& data2) const
|
||||
{
|
||||
if (mySaturated) return Standard_False;
|
||||
N = NextPrimeForMap(NbBuckets);
|
||||
if (N <= myNbBuckets) {
|
||||
if (!myData1)
|
||||
@@ -56,17 +57,17 @@ Standard_Boolean NCollection_BaseMap::BeginResize
|
||||
//=======================================================================
|
||||
|
||||
void NCollection_BaseMap::EndResize
|
||||
(const Standard_Integer theNbBuckets,
|
||||
(const Standard_Integer NbBuckets,
|
||||
const Standard_Integer N,
|
||||
NCollection_ListNode** data1,
|
||||
NCollection_ListNode** data2)
|
||||
{
|
||||
(void )theNbBuckets; // obsolete parameter
|
||||
if (myData1)
|
||||
myAllocator->Free(myData1);
|
||||
if (myData2)
|
||||
myAllocator->Free(myData2);
|
||||
myNbBuckets = N;
|
||||
mySaturated = (myNbBuckets <= NbBuckets);
|
||||
myData1 = data1;
|
||||
myData2 = data2;
|
||||
}
|
||||
@@ -104,6 +105,7 @@ void NCollection_BaseMap::Destroy (NCollection_DelMapNode fDel,
|
||||
mySize = 0;
|
||||
if (doReleaseMemory)
|
||||
{
|
||||
mySaturated = Standard_False;
|
||||
if (myData1)
|
||||
myAllocator->Free(myData1);
|
||||
if (isDouble && myData2)
|
||||
@@ -122,6 +124,7 @@ void NCollection_BaseMap::Statistics(Standard_OStream& S) const
|
||||
{
|
||||
S <<"\nMap Statistics\n---------------\n\n";
|
||||
S <<"This Map has "<<myNbBuckets<<" Buckets and "<<mySize<<" Keys\n\n";
|
||||
if (mySaturated) S<<"The maximum number of Buckets is reached\n";
|
||||
|
||||
if (mySize == 0) return;
|
||||
|
||||
|
@@ -162,9 +162,10 @@ public:
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
: myData1(NULL),
|
||||
myData2(NULL),
|
||||
isDouble(!single),
|
||||
mySaturated(Standard_False),
|
||||
myNbBuckets(NbBuckets),
|
||||
mySize(0),
|
||||
isDouble(!single)
|
||||
mySize(0)
|
||||
{
|
||||
myAllocator = (theAllocator.IsNull() ? NCollection_BaseAllocator::CommonBaseAllocator() : theAllocator);
|
||||
}
|
||||
@@ -188,13 +189,15 @@ public:
|
||||
|
||||
//! Resizable
|
||||
Standard_Boolean Resizable() const
|
||||
{ return IsEmpty() || (mySize > myNbBuckets); }
|
||||
{ return IsEmpty() || (!mySaturated && (mySize > myNbBuckets)); }
|
||||
|
||||
//! Increment
|
||||
Standard_Integer Increment() { return ++mySize; }
|
||||
void Increment()
|
||||
{ mySize++; }
|
||||
|
||||
//! Decrement
|
||||
Standard_Integer Decrement() { return --mySize; }
|
||||
void Decrement()
|
||||
{ mySize--; }
|
||||
|
||||
//! Destroy
|
||||
Standard_EXPORT void Destroy(NCollection_DelMapNode fDel,
|
||||
@@ -210,9 +213,10 @@ public:
|
||||
std::swap (myAllocator, theOther.myAllocator);
|
||||
std::swap (myData1, theOther.myData1);
|
||||
std::swap (myData2, theOther.myData2);
|
||||
//std::swap (isDouble, theOther.isDouble);
|
||||
std::swap (mySaturated, theOther.mySaturated);
|
||||
std::swap (myNbBuckets, theOther.myNbBuckets);
|
||||
std::swap (mySize, theOther.mySize);
|
||||
//std::swap (isDouble, theOther.isDouble);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -223,9 +227,10 @@ public:
|
||||
|
||||
private:
|
||||
// ---------- PRIVATE FIELDS ------------
|
||||
Standard_Boolean isDouble;
|
||||
Standard_Boolean mySaturated;
|
||||
Standard_Integer myNbBuckets;
|
||||
Standard_Integer mySize;
|
||||
Standard_Boolean isDouble;
|
||||
|
||||
// ---------- FRIEND CLASSES ------------
|
||||
friend class Iterator;
|
||||
|
@@ -140,13 +140,10 @@ public:
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ------------
|
||||
|
||||
//! Empty Constructor.
|
||||
NCollection_DataMap() : NCollection_BaseMap (1, Standard_True, Handle(NCollection_BaseAllocator)()) {}
|
||||
|
||||
//! Constructor
|
||||
explicit NCollection_DataMap (const Standard_Integer theNbBuckets,
|
||||
NCollection_DataMap (const Standard_Integer NbBuckets=1,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
|
||||
: NCollection_BaseMap (theNbBuckets, Standard_True, theAllocator) {}
|
||||
: NCollection_BaseMap (NbBuckets, Standard_True, theAllocator) {}
|
||||
|
||||
//! Copy constructor
|
||||
NCollection_DataMap (const NCollection_DataMap& theOther)
|
||||
|
@@ -123,13 +123,10 @@ public:
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ------------
|
||||
|
||||
//! Empty constructor.
|
||||
NCollection_DoubleMap() : NCollection_BaseMap (1, Standard_False, Handle(NCollection_BaseAllocator)()) {}
|
||||
|
||||
//! Constructor
|
||||
explicit NCollection_DoubleMap (const Standard_Integer theNbBuckets,
|
||||
NCollection_DoubleMap (const Standard_Integer NbBuckets=1,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
|
||||
: NCollection_BaseMap (theNbBuckets, Standard_False, theAllocator) {}
|
||||
: NCollection_BaseMap (NbBuckets, Standard_False, theAllocator) {}
|
||||
|
||||
//! Copy constructor
|
||||
NCollection_DoubleMap (const NCollection_DoubleMap& theOther)
|
||||
|
@@ -62,18 +62,25 @@ private:
|
||||
public:
|
||||
//! Constructor with 'Next'
|
||||
IndexedDataMapNode (const TheKeyType& theKey1,
|
||||
const Standard_Integer theIndex,
|
||||
const Standard_Integer theKey2,
|
||||
const TheItemType& theItem,
|
||||
NCollection_ListNode* theNext1)
|
||||
: NCollection_TListNode<TheItemType>(theItem,theNext1),
|
||||
NCollection_ListNode* theNext1,
|
||||
NCollection_ListNode* theNext2) :
|
||||
NCollection_TListNode<TheItemType>(theItem,theNext1),
|
||||
myKey1(theKey1),
|
||||
myIndex (theIndex)
|
||||
myKey2(theKey2),
|
||||
myNext2((IndexedDataMapNode*)theNext2)
|
||||
{
|
||||
}
|
||||
//! Key1
|
||||
TheKeyType& Key1() { return myKey1; }
|
||||
//! Index
|
||||
Standard_Integer& Index() { return myIndex; }
|
||||
TheKeyType& Key1 (void)
|
||||
{ return myKey1; }
|
||||
//! Key2
|
||||
Standard_Integer& Key2 (void)
|
||||
{ return myKey2; }
|
||||
//! Next2
|
||||
IndexedDataMapNode*& Next2 (void)
|
||||
{ return myNext2; }
|
||||
|
||||
//! Static deleter to be passed to BaseList
|
||||
static void delNode (NCollection_ListNode * theNode,
|
||||
@@ -84,7 +91,8 @@ private:
|
||||
}
|
||||
private:
|
||||
TheKeyType myKey1;
|
||||
Standard_Integer myIndex;
|
||||
Standard_Integer myKey2;
|
||||
IndexedDataMapNode * myNext2;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -93,14 +101,13 @@ private:
|
||||
{
|
||||
public:
|
||||
//! Empty constructor
|
||||
Iterator()
|
||||
: myMap (NULL),
|
||||
myNode (NULL),
|
||||
Iterator (void) :
|
||||
myMap(NULL),
|
||||
myIndex(0) {}
|
||||
//! Constructor
|
||||
Iterator (const NCollection_IndexedDataMap& theMap)
|
||||
: myMap ((NCollection_IndexedDataMap* )&theMap),
|
||||
myNode (!theMap.IsEmpty() ? (IndexedDataMapNode* )myMap->myData2[0] : NULL),
|
||||
myNode (myMap->nodeFromIndex (1)),
|
||||
myIndex (1) {}
|
||||
//! Query if the end of collection is reached by iterator
|
||||
Standard_Boolean More(void) const
|
||||
@@ -108,7 +115,7 @@ private:
|
||||
//! Make a step along the collection
|
||||
void Next(void)
|
||||
{
|
||||
myNode = (IndexedDataMapNode* )myMap->myData2[++myIndex - 1];
|
||||
myNode = myMap->nodeFromIndex (++myIndex);
|
||||
}
|
||||
//! Value access
|
||||
const TheItemType& Value(void) const
|
||||
@@ -162,13 +169,10 @@ private:
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ------------
|
||||
|
||||
//! Empty constructor.
|
||||
NCollection_IndexedDataMap() : NCollection_BaseMap (1, Standard_False, Handle(NCollection_BaseAllocator)()) {}
|
||||
|
||||
//! Constructor
|
||||
explicit NCollection_IndexedDataMap (const Standard_Integer theNbBuckets,
|
||||
NCollection_IndexedDataMap (const Standard_Integer NbBuckets=1,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
|
||||
: NCollection_BaseMap (theNbBuckets, Standard_False, theAllocator) {}
|
||||
: NCollection_BaseMap (NbBuckets, Standard_False, theAllocator) {}
|
||||
|
||||
//! Copy constructor
|
||||
NCollection_IndexedDataMap (const NCollection_IndexedDataMap& theOther)
|
||||
@@ -191,14 +195,18 @@ private:
|
||||
|
||||
Clear();
|
||||
ReSize (theOther.Extent()-1);
|
||||
for (Standard_Integer anIndexIter = 1; anIndexIter <= theOther.Extent(); ++anIndexIter)
|
||||
Standard_Integer i;
|
||||
for (i=1; i<=theOther.Extent(); i++)
|
||||
{
|
||||
const TheKeyType& aKey1 = theOther.FindKey (anIndexIter);
|
||||
const TheItemType& anItem = theOther.FindFromIndex(anIndexIter);
|
||||
const Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
|
||||
IndexedDataMapNode* pNode = new (this->myAllocator) IndexedDataMapNode (aKey1, anIndexIter, anItem, myData1[iK1]);
|
||||
TheKeyType aKey1 = theOther.FindKey(i);
|
||||
TheItemType anItem = theOther.FindFromIndex(i);
|
||||
Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
|
||||
Standard_Integer iK2 = ::HashCode (i, NbBuckets());
|
||||
IndexedDataMapNode * pNode =
|
||||
new (this->myAllocator) IndexedDataMapNode (aKey1, i, anItem,
|
||||
myData1[iK1], myData2[iK2]);
|
||||
myData1[iK1] = pNode;
|
||||
myData2[anIndexIter - 1] = pNode;
|
||||
myData2[iK2] = pNode;
|
||||
Increment();
|
||||
}
|
||||
return *this;
|
||||
@@ -220,18 +228,22 @@ private:
|
||||
{
|
||||
if (myData1)
|
||||
{
|
||||
memcpy (ppNewData2, myData2, sizeof(IndexedDataMapNode*) * Extent());
|
||||
for (Standard_Integer aBucketIter = 0; aBucketIter <= NbBuckets(); ++aBucketIter)
|
||||
IndexedDataMapNode *p, *q;
|
||||
Standard_Integer i, iK1, iK2;
|
||||
for (i = 0; i <= NbBuckets(); i++)
|
||||
{
|
||||
if (myData1[aBucketIter])
|
||||
if (myData1[i])
|
||||
{
|
||||
IndexedDataMapNode* p = (IndexedDataMapNode *) myData1[aBucketIter];
|
||||
p = (IndexedDataMapNode *) myData1[i];
|
||||
while (p)
|
||||
{
|
||||
const Standard_Integer iK1 = Hasher::HashCode (p->Key1(), newBuck);
|
||||
IndexedDataMapNode* q = (IndexedDataMapNode* )p->Next();
|
||||
iK1 = Hasher::HashCode (p->Key1(), newBuck);
|
||||
iK2 = ::HashCode (p->Key2(), newBuck);
|
||||
q = (IndexedDataMapNode*) p->Next();
|
||||
p->Next() = ppNewData1[iK1];
|
||||
p->Next2() = (IndexedDataMapNode*)ppNewData2[iK2];
|
||||
ppNewData1[iK1] = p;
|
||||
ppNewData2[iK2] = p;
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
@@ -245,26 +257,23 @@ private:
|
||||
Standard_Integer Add (const TheKeyType& theKey1, const TheItemType& theItem)
|
||||
{
|
||||
if (Resizable())
|
||||
{
|
||||
ReSize(Extent());
|
||||
}
|
||||
|
||||
const Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
|
||||
IndexedDataMapNode* pNode = (IndexedDataMapNode* )myData1[iK1];
|
||||
Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
|
||||
IndexedDataMapNode * pNode;
|
||||
pNode = (IndexedDataMapNode *) myData1[iK1];
|
||||
while (pNode)
|
||||
{
|
||||
if (Hasher::IsEqual (pNode->Key1(), theKey1))
|
||||
{
|
||||
return pNode->Index();
|
||||
}
|
||||
return pNode->Key2();
|
||||
pNode = (IndexedDataMapNode *) pNode->Next();
|
||||
}
|
||||
|
||||
const Standard_Integer aNewIndex = Increment();
|
||||
pNode = new (this->myAllocator) IndexedDataMapNode (theKey1, aNewIndex, theItem, myData1[iK1]);
|
||||
Increment();
|
||||
Standard_Integer iK2 = ::HashCode(Extent(),NbBuckets());
|
||||
pNode = new (this->myAllocator) IndexedDataMapNode (theKey1, Extent(), theItem,
|
||||
myData1[iK1], myData2[iK2]);
|
||||
myData1[iK1] = pNode;
|
||||
myData2[aNewIndex - 1] = pNode;
|
||||
return aNewIndex;
|
||||
myData2[iK2] = pNode;
|
||||
return Extent();
|
||||
}
|
||||
|
||||
//! Contains
|
||||
@@ -293,14 +302,15 @@ private:
|
||||
"NCollection_IndexedDataMap::Substitute : "
|
||||
"Index is out of range");
|
||||
|
||||
IndexedDataMapNode * p;
|
||||
// check if theKey1 is not already in the map
|
||||
const Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
|
||||
IndexedDataMapNode* p = (IndexedDataMapNode *) myData1[iK1];
|
||||
Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
|
||||
p = (IndexedDataMapNode *) myData1[iK1];
|
||||
while (p)
|
||||
{
|
||||
if (Hasher::IsEqual (p->Key1(), theKey1))
|
||||
{
|
||||
if (p->Index() != theIndex)
|
||||
if (p->Key2() != theIndex)
|
||||
{
|
||||
throw Standard_DomainError ("NCollection_IndexedDataMap::Substitute : "
|
||||
"Attempt to substitute existing key");
|
||||
@@ -313,10 +323,17 @@ private:
|
||||
}
|
||||
|
||||
// Find the node for the index I
|
||||
p = (IndexedDataMapNode* )myData2[theIndex - 1];
|
||||
Standard_Integer iK2 = ::HashCode (theIndex, NbBuckets());
|
||||
p = (IndexedDataMapNode *) myData2[iK2];
|
||||
while (p)
|
||||
{
|
||||
if (p->Key2() == theIndex)
|
||||
break;
|
||||
p = (IndexedDataMapNode*) p->Next2();
|
||||
}
|
||||
|
||||
// remove the old key
|
||||
const Standard_Integer iK = Hasher::HashCode (p->Key1(), NbBuckets());
|
||||
Standard_Integer iK = Hasher::HashCode (p->Key1(), NbBuckets());
|
||||
IndexedDataMapNode * q = (IndexedDataMapNode *) myData1[iK];
|
||||
if (q == p)
|
||||
myData1[iK] = (IndexedDataMapNode *) p->Next();
|
||||
@@ -346,26 +363,71 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
IndexedDataMapNode* aP1 = (IndexedDataMapNode* )myData2[theIndex1 - 1];
|
||||
IndexedDataMapNode* aP2 = (IndexedDataMapNode* )myData2[theIndex2 - 1];
|
||||
std::swap (aP1->Index(), aP2->Index());
|
||||
myData2[theIndex2 - 1] = aP1;
|
||||
myData2[theIndex1 - 1] = aP2;
|
||||
const Standard_Integer aK1 = ::HashCode (theIndex1, NbBuckets());
|
||||
const Standard_Integer aK2 = ::HashCode (theIndex2, NbBuckets());
|
||||
|
||||
IndexedDataMapNode* aP1 = (IndexedDataMapNode*) myData2[aK1];
|
||||
IndexedDataMapNode* aP2 = (IndexedDataMapNode*) myData2[aK2];
|
||||
|
||||
if (aP1->Key2() == theIndex1)
|
||||
{
|
||||
myData2[aK1] = (IndexedDataMapNode *) aP1->Next2();
|
||||
}
|
||||
else
|
||||
{
|
||||
IndexedDataMapNode* aQ = aP1;
|
||||
for (aP1 = aQ->Next2(); aP1->Key2() != theIndex1; aQ = aP1, aP1 = aQ->Next2()) { }
|
||||
|
||||
aQ->Next2() = aP1->Next2();
|
||||
}
|
||||
|
||||
if (aP2->Key2() == theIndex2)
|
||||
{
|
||||
myData2[aK2] = (IndexedDataMapNode *) aP2->Next2();
|
||||
}
|
||||
else
|
||||
{
|
||||
IndexedDataMapNode* aQ = aP2;
|
||||
for (aP2 = aQ->Next2(); aP2->Key2() != theIndex2; aQ = aP2, aP2 = aQ->Next2()) { }
|
||||
|
||||
aQ->Next2() = aP2->Next2();
|
||||
}
|
||||
|
||||
std::swap (aP1->Key2(),
|
||||
aP2->Key2());
|
||||
|
||||
aP1->Next2() = (IndexedDataMapNode*) myData2[aK2];
|
||||
myData2[aK2] = aP1;
|
||||
|
||||
aP2->Next2() = (IndexedDataMapNode*) myData2[aK1];
|
||||
myData2[aK1] = aP2;
|
||||
}
|
||||
|
||||
//! RemoveLast
|
||||
void RemoveLast (void)
|
||||
{
|
||||
const Standard_Integer aLastIndex = Extent();
|
||||
Standard_OutOfRange_Raise_if (aLastIndex == 0, "NCollection_IndexedDataMap::RemoveLast");
|
||||
Standard_OutOfRange_Raise_if (Extent() == 0, "NCollection_IndexedDataMap::RemoveLast");
|
||||
|
||||
IndexedDataMapNode * p, * q;
|
||||
// Find the node for the last index and remove it
|
||||
IndexedDataMapNode* p = (IndexedDataMapNode* )myData2[aLastIndex - 1];
|
||||
myData2[aLastIndex - 1] = NULL;
|
||||
Standard_Integer iK2 = ::HashCode (Extent(), NbBuckets());
|
||||
p = (IndexedDataMapNode *) myData2[iK2];
|
||||
q = NULL;
|
||||
while (p)
|
||||
{
|
||||
if (p->Key2() == Extent())
|
||||
break;
|
||||
q = p;
|
||||
p = (IndexedDataMapNode*) p->Next2();
|
||||
}
|
||||
if (q == NULL)
|
||||
myData2[iK2] = (IndexedDataMapNode *) p->Next2();
|
||||
else
|
||||
q->Next2() = p->Next2();
|
||||
|
||||
// remove the key
|
||||
const Standard_Integer iK1 = Hasher::HashCode (p->Key1(), NbBuckets());
|
||||
IndexedDataMapNode* q = (IndexedDataMapNode *) myData1[iK1];
|
||||
Standard_Integer iK1 = Hasher::HashCode (p->Key1(), NbBuckets());
|
||||
q = (IndexedDataMapNode *) myData1[iK1];
|
||||
if (q == p)
|
||||
myData1[iK1] = (IndexedDataMapNode *) p->Next();
|
||||
else
|
||||
@@ -381,14 +443,12 @@ private:
|
||||
|
||||
//! Remove the key of the given index.
|
||||
//! Caution! The index of the last key can be changed.
|
||||
void RemoveFromIndex(const Standard_Integer theIndex)
|
||||
void RemoveFromIndex(const Standard_Integer theKey2)
|
||||
{
|
||||
const Standard_Integer aLastInd = Extent();
|
||||
Standard_OutOfRange_Raise_if(theIndex < 1 || theIndex > aLastInd, "NCollection_IndexedDataMap::Remove");
|
||||
if (theIndex != aLastInd)
|
||||
{
|
||||
Swap (theIndex, aLastInd);
|
||||
}
|
||||
Standard_OutOfRange_Raise_if(theKey2 < 1 || theKey2 > Extent(), "NCollection_IndexedDataMap::Remove");
|
||||
Standard_Integer aLastInd = Extent();
|
||||
if (theKey2 != aLastInd)
|
||||
Swap(theKey2, aLastInd);
|
||||
RemoveLast();
|
||||
}
|
||||
|
||||
@@ -403,46 +463,62 @@ private:
|
||||
}
|
||||
|
||||
//! FindKey
|
||||
const TheKeyType& FindKey (const Standard_Integer theIndex) const
|
||||
const TheKeyType& FindKey (const Standard_Integer theKey2) const
|
||||
{
|
||||
Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > Extent(), "NCollection_IndexedDataMap::FindKey");
|
||||
IndexedDataMapNode* aNode = (IndexedDataMapNode* )myData2[theIndex - 1];
|
||||
Standard_OutOfRange_Raise_if (theKey2 < 1 || theKey2 > Extent(), "NCollection_IndexedDataMap::FindKey");
|
||||
|
||||
IndexedDataMapNode* aNode = nodeFromIndex (theKey2);
|
||||
if (aNode == NULL)
|
||||
{
|
||||
throw Standard_NoSuchObject("NCollection_IndexedDataMap::FindKey");
|
||||
}
|
||||
return aNode->Key1();
|
||||
}
|
||||
|
||||
//! FindFromIndex
|
||||
const TheItemType& FindFromIndex (const Standard_Integer theIndex) const
|
||||
const TheItemType& FindFromIndex (const Standard_Integer theKey2) const
|
||||
{
|
||||
Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > Extent(), "NCollection_IndexedDataMap::FindFromIndex");
|
||||
IndexedDataMapNode* aNode = (IndexedDataMapNode* )myData2[theIndex - 1];
|
||||
Standard_OutOfRange_Raise_if (theKey2 < 1 || theKey2 > Extent(), "NCollection_IndexedDataMap::FindFromIndex");
|
||||
|
||||
IndexedDataMapNode* aNode = nodeFromIndex (theKey2);
|
||||
if (aNode == NULL)
|
||||
{
|
||||
throw Standard_NoSuchObject("NCollection_IndexedDataMap::FindFromIndex");
|
||||
}
|
||||
return aNode->Value();
|
||||
}
|
||||
|
||||
//! operator ()
|
||||
const TheItemType& operator() (const Standard_Integer theIndex) const { return FindFromIndex (theIndex); }
|
||||
const TheItemType& operator() (const Standard_Integer theKey2) const
|
||||
{ return FindFromIndex (theKey2); }
|
||||
|
||||
//! ChangeFromIndex
|
||||
TheItemType& ChangeFromIndex (const Standard_Integer theIndex)
|
||||
TheItemType& ChangeFromIndex (const Standard_Integer theKey2)
|
||||
{
|
||||
Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > Extent(), "NCollection_IndexedDataMap::ChangeFromIndex");
|
||||
IndexedDataMapNode* aNode = (IndexedDataMapNode* )myData2[theIndex - 1];
|
||||
Standard_OutOfRange_Raise_if (theKey2 < 1 || theKey2 > Extent(), "NCollection_IndexedDataMap::ChangeFromIndex");
|
||||
|
||||
IndexedDataMapNode* aNode = nodeFromIndex (theKey2);
|
||||
if (aNode == NULL)
|
||||
{
|
||||
throw Standard_NoSuchObject("NCollection_IndexedDataMap::ChangeFromIndex");
|
||||
}
|
||||
return aNode->ChangeValue();
|
||||
}
|
||||
|
||||
//! operator ()
|
||||
TheItemType& operator() (const Standard_Integer theIndex) { return ChangeFromIndex (theIndex); }
|
||||
TheItemType& operator() (const Standard_Integer theKey2)
|
||||
{ return ChangeFromIndex (theKey2); }
|
||||
|
||||
//! FindIndex
|
||||
Standard_Integer FindIndex(const TheKeyType& theKey1) const
|
||||
{
|
||||
if (IsEmpty()) return 0;
|
||||
IndexedDataMapNode* pNode1 = (IndexedDataMapNode* )myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
IndexedDataMapNode * pNode1 =
|
||||
(IndexedDataMapNode *) myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
while (pNode1)
|
||||
{
|
||||
if (Hasher::IsEqual (pNode1->Key1(), theKey1))
|
||||
{
|
||||
return pNode1->Index();
|
||||
}
|
||||
return pNode1->Key2();
|
||||
pNode1 = (IndexedDataMapNode*) pNode1->Next();
|
||||
}
|
||||
return 0;
|
||||
@@ -453,13 +529,12 @@ private:
|
||||
{
|
||||
Standard_NoSuchObject_Raise_if (IsEmpty(), "NCollection_IndexedDataMap::FindFromKey");
|
||||
|
||||
IndexedDataMapNode* pNode1 = (IndexedDataMapNode* )myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
IndexedDataMapNode * pNode1 =
|
||||
(IndexedDataMapNode *) myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
while (pNode1)
|
||||
{
|
||||
if (Hasher::IsEqual (pNode1->Key1(), theKey1))
|
||||
{
|
||||
return pNode1->Value();
|
||||
}
|
||||
pNode1 = (IndexedDataMapNode*) pNode1->Next();
|
||||
}
|
||||
throw Standard_NoSuchObject("NCollection_IndexedDataMap::FindFromKey");
|
||||
@@ -470,13 +545,12 @@ private:
|
||||
{
|
||||
Standard_NoSuchObject_Raise_if (IsEmpty(), "NCollection_IndexedDataMap::ChangeFromKey");
|
||||
|
||||
IndexedDataMapNode* pNode1 = (IndexedDataMapNode* )myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
IndexedDataMapNode * pNode1 =
|
||||
(IndexedDataMapNode *) myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
while (pNode1)
|
||||
{
|
||||
if (Hasher::IsEqual (pNode1->Key1(), theKey1))
|
||||
{
|
||||
return pNode1->ChangeValue();
|
||||
}
|
||||
pNode1 = (IndexedDataMapNode*) pNode1->Next();
|
||||
}
|
||||
throw Standard_NoSuchObject("NCollection_IndexedDataMap::ChangeFromKey");
|
||||
@@ -497,13 +571,12 @@ private:
|
||||
{
|
||||
if (!IsEmpty())
|
||||
{
|
||||
IndexedDataMapNode* pNode1 = (IndexedDataMapNode* )myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
IndexedDataMapNode * pNode1 =
|
||||
(IndexedDataMapNode *) myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
while (pNode1)
|
||||
{
|
||||
if (Hasher::IsEqual (pNode1->Key1(), theKey1))
|
||||
{
|
||||
return &pNode1->ChangeValue();
|
||||
}
|
||||
pNode1 = (IndexedDataMapNode*) pNode1->Next();
|
||||
}
|
||||
}
|
||||
@@ -555,6 +628,25 @@ private:
|
||||
private:
|
||||
// ----------- PRIVATE METHODS -----------
|
||||
|
||||
//! Find map node associated with specified index.
|
||||
//! Return NULL if not found (exception-free internal implementation).
|
||||
IndexedDataMapNode* nodeFromIndex (const Standard_Integer theKey2) const
|
||||
{
|
||||
if (Extent() == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
for (IndexedDataMapNode* aNode = (IndexedDataMapNode* )myData2[::HashCode (theKey2, NbBuckets())];
|
||||
aNode != NULL; aNode = (IndexedDataMapNode* )aNode->Next2())
|
||||
{
|
||||
if (aNode->Key2() == theKey2)
|
||||
{
|
||||
return aNode;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -45,23 +45,29 @@ public:
|
||||
typedef TheKeyType key_type;
|
||||
|
||||
private:
|
||||
//! Adaptation of the TListNode to the INDEXEDmap
|
||||
// **************** Adaptation of the TListNode to the INDEXEDmap
|
||||
class IndexedMapNode : public NCollection_TListNode<TheKeyType>
|
||||
{
|
||||
public:
|
||||
//! Constructor with 'Next'
|
||||
IndexedMapNode (const TheKeyType& theKey1,
|
||||
const Standard_Integer theIndex,
|
||||
NCollection_ListNode* theNext1)
|
||||
: NCollection_TListNode<TheKeyType> (theKey1, theNext1),
|
||||
myIndex (theIndex)
|
||||
const Standard_Integer theKey2,
|
||||
NCollection_ListNode* theNext1,
|
||||
NCollection_ListNode* theNext2) :
|
||||
NCollection_TListNode<TheKeyType> (theKey1, theNext1),
|
||||
myKey2(theKey2),
|
||||
myNext2((IndexedMapNode*)theNext2)
|
||||
{
|
||||
}
|
||||
//! Key1
|
||||
TheKeyType& Key1() { return this->ChangeValue(); }
|
||||
|
||||
//! Index
|
||||
Standard_Integer& Index() { return myIndex; }
|
||||
TheKeyType& Key1 (void)
|
||||
{ return this->ChangeValue(); }
|
||||
//! Key2
|
||||
Standard_Integer& Key2 (void)
|
||||
{ return myKey2; }
|
||||
//! Next2
|
||||
IndexedMapNode*& Next2 (void)
|
||||
{ return myNext2; }
|
||||
|
||||
//! Static deleter to be passed to BaseList
|
||||
static void delNode (NCollection_ListNode * theNode,
|
||||
@@ -72,7 +78,8 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
Standard_Integer myIndex;
|
||||
Standard_Integer myKey2;
|
||||
IndexedMapNode * myNext2;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -124,13 +131,10 @@ private:
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ------------
|
||||
|
||||
//! Empty constructor.
|
||||
NCollection_IndexedMap() : NCollection_BaseMap (1, Standard_False, Handle(NCollection_BaseAllocator)()) {}
|
||||
|
||||
//! Constructor
|
||||
explicit NCollection_IndexedMap (const Standard_Integer theNbBuckets,
|
||||
NCollection_IndexedMap (const Standard_Integer NbBuckets=1,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator=0L)
|
||||
: NCollection_BaseMap (theNbBuckets, Standard_False, theAllocator) {}
|
||||
: NCollection_BaseMap (NbBuckets, Standard_False, theAllocator) {}
|
||||
|
||||
//! Copy constructor
|
||||
NCollection_IndexedMap (const NCollection_IndexedMap& theOther)
|
||||
@@ -153,14 +157,17 @@ private:
|
||||
|
||||
Clear();
|
||||
ReSize (theOther.Extent()-1);
|
||||
const Standard_Integer iLength = theOther.Extent();
|
||||
for (Standard_Integer anIndexIter = 1; anIndexIter <= iLength; ++anIndexIter)
|
||||
Standard_Integer i, iLength=theOther.Extent();
|
||||
for (i=1; i<=iLength; i++)
|
||||
{
|
||||
const TheKeyType& aKey1 = theOther.FindKey (anIndexIter);
|
||||
const Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
|
||||
IndexedMapNode* pNode = new (this->myAllocator) IndexedMapNode (aKey1, anIndexIter, myData1[iK1]);
|
||||
TheKeyType aKey1 = theOther(i);
|
||||
Standard_Integer iK1 = Hasher::HashCode (aKey1, NbBuckets());
|
||||
Standard_Integer iK2 = ::HashCode (i, NbBuckets());
|
||||
IndexedMapNode * pNode = new (this->myAllocator) IndexedMapNode (aKey1, i,
|
||||
myData1[iK1],
|
||||
myData2[iK2]);
|
||||
myData1[iK1] = pNode;
|
||||
myData2[anIndexIter - 1] = pNode;
|
||||
myData2[iK2] = pNode;
|
||||
Increment();
|
||||
}
|
||||
return *this;
|
||||
@@ -173,33 +180,40 @@ private:
|
||||
}
|
||||
|
||||
//! ReSize
|
||||
void ReSize (const Standard_Integer theExtent)
|
||||
void ReSize (const Standard_Integer N)
|
||||
{
|
||||
NCollection_ListNode** ppNewData1 = NULL;
|
||||
NCollection_ListNode** ppNewData2 = NULL;
|
||||
Standard_Integer newBuck;
|
||||
if (BeginResize (theExtent, newBuck, ppNewData1, ppNewData2))
|
||||
if (BeginResize (N, newBuck, ppNewData1, ppNewData2))
|
||||
{
|
||||
if (myData1)
|
||||
{
|
||||
memcpy (ppNewData2, myData2, sizeof(IndexedMapNode*) * Extent());
|
||||
for (Standard_Integer aBucketIter = 0; aBucketIter <= NbBuckets(); ++aBucketIter)
|
||||
IndexedMapNode *p, *q;
|
||||
Standard_Integer i, iK1, iK2;
|
||||
for (i = 0; i <= NbBuckets(); i++)
|
||||
{
|
||||
if (myData1[aBucketIter])
|
||||
if (myData1[i])
|
||||
{
|
||||
IndexedMapNode* p = (IndexedMapNode* )myData1[aBucketIter];
|
||||
p = (IndexedMapNode *) myData1[i];
|
||||
while (p)
|
||||
{
|
||||
const Standard_Integer iK1 = Hasher::HashCode (p->Key1(), newBuck);
|
||||
IndexedMapNode* q = (IndexedMapNode* )p->Next();
|
||||
iK1 =Hasher::HashCode(p->Key1(), newBuck);
|
||||
q = (IndexedMapNode*) p->Next();
|
||||
p->Next() = ppNewData1[iK1];
|
||||
ppNewData1[iK1] = p;
|
||||
if (p->Key2() > 0)
|
||||
{
|
||||
iK2 = ::HashCode (p->Key2(), newBuck);
|
||||
p->Next2() = (IndexedMapNode*)ppNewData2[iK2];
|
||||
ppNewData2[iK2] = p;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EndResize (theExtent, newBuck, ppNewData1, ppNewData2);
|
||||
EndResize (N, newBuck, ppNewData1, ppNewData2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,26 +221,23 @@ private:
|
||||
Standard_Integer Add (const TheKeyType& theKey1)
|
||||
{
|
||||
if (Resizable())
|
||||
{
|
||||
ReSize(Extent());
|
||||
}
|
||||
|
||||
Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
|
||||
IndexedMapNode* pNode = (IndexedMapNode* )myData1[iK1];
|
||||
IndexedMapNode * pNode;
|
||||
pNode = (IndexedMapNode *) myData1[iK1];
|
||||
while (pNode)
|
||||
{
|
||||
if (Hasher::IsEqual (pNode->Key1(), theKey1))
|
||||
{
|
||||
return pNode->Index();
|
||||
}
|
||||
return pNode->Key2();
|
||||
pNode = (IndexedMapNode *) pNode->Next();
|
||||
}
|
||||
|
||||
const Standard_Integer aNewIndex = Increment();
|
||||
pNode = new (this->myAllocator) IndexedMapNode (theKey1, aNewIndex, myData1[iK1]);
|
||||
Increment();
|
||||
Standard_Integer iK2 = ::HashCode(Extent(),NbBuckets());
|
||||
pNode = new (this->myAllocator) IndexedMapNode (theKey1, Extent(),
|
||||
myData1[iK1], myData2[iK2]);
|
||||
myData1[iK1] = pNode;
|
||||
myData2[aNewIndex - 1] = pNode;
|
||||
return aNewIndex;
|
||||
myData2[iK2] = pNode;
|
||||
return Extent();
|
||||
}
|
||||
|
||||
//! Contains
|
||||
@@ -254,14 +265,15 @@ private:
|
||||
"NCollection_IndexedMap::Substitute : "
|
||||
"Index is out of range");
|
||||
|
||||
IndexedMapNode * p;
|
||||
// check if theKey1 is not already in the map
|
||||
Standard_Integer iK1 = Hasher::HashCode (theKey1, NbBuckets());
|
||||
IndexedMapNode* p = (IndexedMapNode *) myData1[iK1];
|
||||
p = (IndexedMapNode *) myData1[iK1];
|
||||
while (p)
|
||||
{
|
||||
if (Hasher::IsEqual (p->Key1(), theKey1))
|
||||
{
|
||||
if (p->Index() != theIndex)
|
||||
if (p->Key2() != theIndex)
|
||||
{
|
||||
throw Standard_DomainError ("NCollection_IndexedMap::Substitute : "
|
||||
"Attempt to substitute existing key");
|
||||
@@ -273,7 +285,14 @@ private:
|
||||
}
|
||||
|
||||
// Find the node for the index I
|
||||
p = (IndexedMapNode* )myData2[theIndex - 1];
|
||||
Standard_Integer iK2 = ::HashCode (theIndex, NbBuckets());
|
||||
p = (IndexedMapNode *) myData2[iK2];
|
||||
while (p)
|
||||
{
|
||||
if (p->Key2() == theIndex)
|
||||
break;
|
||||
p = (IndexedMapNode*) p->Next2();
|
||||
}
|
||||
|
||||
// remove the old key
|
||||
Standard_Integer iK = Hasher::HashCode (p->Key1(), NbBuckets());
|
||||
@@ -305,26 +324,71 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
IndexedMapNode* aP1 = (IndexedMapNode* )myData2[theIndex1 - 1];
|
||||
IndexedMapNode* aP2 = (IndexedMapNode* )myData2[theIndex2 - 1];
|
||||
std::swap (aP1->Index(), aP2->Index());
|
||||
myData2[theIndex2 - 1] = aP1;
|
||||
myData2[theIndex1 - 1] = aP2;
|
||||
const Standard_Integer aK1 = ::HashCode (theIndex1, NbBuckets());
|
||||
const Standard_Integer aK2 = ::HashCode (theIndex2, NbBuckets());
|
||||
|
||||
IndexedMapNode* aP1 = (IndexedMapNode*) myData2[aK1];
|
||||
IndexedMapNode* aP2 = (IndexedMapNode*) myData2[aK2];
|
||||
|
||||
if (aP1->Key2() == theIndex1)
|
||||
{
|
||||
myData2[aK1] = (IndexedMapNode *) aP1->Next2();
|
||||
}
|
||||
else
|
||||
{
|
||||
IndexedMapNode* aQ = aP1;
|
||||
for (aP1 = aQ->Next2(); aP1->Key2() != theIndex1; aQ = aP1, aP1 = aQ->Next2()) { }
|
||||
|
||||
aQ->Next2() = aP1->Next2();
|
||||
}
|
||||
|
||||
if (aP2->Key2() == theIndex2)
|
||||
{
|
||||
myData2[aK2] = (IndexedMapNode *) aP2->Next2();
|
||||
}
|
||||
else
|
||||
{
|
||||
IndexedMapNode* aQ = aP2;
|
||||
for (aP2 = aQ->Next2(); aP2->Key2() != theIndex2; aQ = aP2, aP2 = aQ->Next2()) { }
|
||||
|
||||
aQ->Next2() = aP2->Next2();
|
||||
}
|
||||
|
||||
std::swap (aP1->Key2(),
|
||||
aP2->Key2());
|
||||
|
||||
aP1->Next2() = (IndexedMapNode*) myData2[aK2];
|
||||
myData2[aK2] = aP1;
|
||||
|
||||
aP2->Next2() = (IndexedMapNode*) myData2[aK1];
|
||||
myData2[aK1] = aP2;
|
||||
}
|
||||
|
||||
//! RemoveLast
|
||||
void RemoveLast (void)
|
||||
{
|
||||
const Standard_Integer aLastIndex = Extent();
|
||||
Standard_OutOfRange_Raise_if (aLastIndex == 0, "NCollection_IndexedMap::RemoveLast");
|
||||
Standard_OutOfRange_Raise_if (Extent() == 0, "NCollection_IndexedMap::RemoveLast");
|
||||
|
||||
IndexedMapNode * p, * q;
|
||||
// Find the node for the last index and remove it
|
||||
IndexedMapNode* p = (IndexedMapNode* )myData2[aLastIndex - 1];
|
||||
myData2[aLastIndex - 1] = NULL;
|
||||
Standard_Integer iK2 = ::HashCode (Extent(), NbBuckets());
|
||||
p = (IndexedMapNode *) myData2[iK2];
|
||||
q = NULL;
|
||||
while (p)
|
||||
{
|
||||
if (p->Key2() == Extent())
|
||||
break;
|
||||
q = p;
|
||||
p = (IndexedMapNode*) p->Next2();
|
||||
}
|
||||
if (q == NULL)
|
||||
myData2[iK2] = (IndexedMapNode *) p->Next2();
|
||||
else
|
||||
q->Next2() = p->Next2();
|
||||
|
||||
// remove the key
|
||||
Standard_Integer iK1 = Hasher::HashCode (p->Key1(), NbBuckets());
|
||||
IndexedMapNode* q = (IndexedMapNode *) myData1[iK1];
|
||||
q = (IndexedMapNode *) myData1[iK1];
|
||||
if (q == p)
|
||||
myData1[iK1] = (IndexedMapNode *) p->Next();
|
||||
else
|
||||
@@ -340,14 +404,12 @@ private:
|
||||
|
||||
//! Remove the key of the given index.
|
||||
//! Caution! The index of the last key can be changed.
|
||||
void RemoveFromIndex(const Standard_Integer theIndex)
|
||||
void RemoveFromIndex(const Standard_Integer theKey2)
|
||||
{
|
||||
Standard_OutOfRange_Raise_if(theIndex < 1 || theIndex > Extent(), "NCollection_IndexedMap::RemoveFromIndex");
|
||||
const Standard_Integer aLastInd = Extent();
|
||||
if (theIndex != aLastInd)
|
||||
{
|
||||
Swap(theIndex, aLastInd);
|
||||
}
|
||||
Standard_OutOfRange_Raise_if(theKey2 < 1 || theKey2 > Extent(), "NCollection_IndexedMap::Remove");
|
||||
Standard_Integer aLastInd = Extent();
|
||||
if (theKey2 != aLastInd)
|
||||
Swap(theKey2, aLastInd);
|
||||
RemoveLast();
|
||||
}
|
||||
|
||||
@@ -366,28 +428,35 @@ private:
|
||||
}
|
||||
|
||||
//! FindKey
|
||||
const TheKeyType& FindKey (const Standard_Integer theIndex) const
|
||||
const TheKeyType& FindKey (const Standard_Integer theKey2) const
|
||||
{
|
||||
Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > Extent(), "NCollection_IndexedMap::FindKey");
|
||||
IndexedMapNode* pNode2 = (IndexedMapNode* )myData2[theIndex - 1];
|
||||
Standard_OutOfRange_Raise_if (theKey2 < 1 || theKey2 > Extent(), "NCollection_IndexedMap::FindKey");
|
||||
|
||||
IndexedMapNode * pNode2 =
|
||||
(IndexedMapNode *) myData2[::HashCode(theKey2,NbBuckets())];
|
||||
while (pNode2)
|
||||
{
|
||||
if (pNode2->Key2() == theKey2)
|
||||
return pNode2->Key1();
|
||||
pNode2 = (IndexedMapNode*) pNode2->Next2();
|
||||
}
|
||||
throw Standard_NoSuchObject("NCollection_IndexedMap::FindKey");
|
||||
}
|
||||
|
||||
//! operator ()
|
||||
const TheKeyType& operator() (const Standard_Integer theIndex) const
|
||||
{ return FindKey (theIndex); }
|
||||
const TheKeyType& operator() (const Standard_Integer theKey2) const
|
||||
{ return FindKey (theKey2); }
|
||||
|
||||
//! FindIndex
|
||||
Standard_Integer FindIndex(const TheKeyType& theKey1) const
|
||||
{
|
||||
if (IsEmpty()) return 0;
|
||||
IndexedMapNode* pNode1 = (IndexedMapNode* )myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
IndexedMapNode * pNode1 =
|
||||
(IndexedMapNode *) myData1[Hasher::HashCode(theKey1,NbBuckets())];
|
||||
while (pNode1)
|
||||
{
|
||||
if (Hasher::IsEqual (pNode1->Key1(), theKey1))
|
||||
{
|
||||
return pNode1->Index();
|
||||
}
|
||||
return pNode1->Key2();
|
||||
pNode1 = (IndexedMapNode*) pNode1->Next();
|
||||
}
|
||||
return 0;
|
||||
|
@@ -58,11 +58,9 @@ public:
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ------------
|
||||
|
||||
//! Empty constructor.
|
||||
NCollection_List() : NCollection_BaseList(Handle(NCollection_BaseAllocator)()) {}
|
||||
|
||||
//! Constructor
|
||||
explicit NCollection_List(const Handle(NCollection_BaseAllocator)& theAllocator) : NCollection_BaseList(theAllocator) {}
|
||||
NCollection_List(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
|
||||
NCollection_BaseList(theAllocator) {}
|
||||
|
||||
//! Copy constructor
|
||||
NCollection_List (const NCollection_List& theOther) :
|
||||
|
@@ -24,7 +24,7 @@ template<class theItem, Standard_Integer MAX_ARRAY_SIZE = 1024> class NCollectio
|
||||
{
|
||||
public:
|
||||
|
||||
explicit NCollection_LocalArray (const size_t theSize)
|
||||
NCollection_LocalArray (const size_t theSize)
|
||||
: myPtr (myBuffer)
|
||||
{
|
||||
Allocate(theSize);
|
||||
|
@@ -119,13 +119,10 @@ public:
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ------------
|
||||
|
||||
//! Empty constructor.
|
||||
NCollection_Map() : NCollection_BaseMap (1, Standard_True, Handle(NCollection_BaseAllocator)()) {}
|
||||
|
||||
//! Constructor
|
||||
explicit NCollection_Map (const Standard_Integer theNbBuckets,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator = 0L)
|
||||
: NCollection_BaseMap (theNbBuckets, Standard_True, theAllocator) {}
|
||||
NCollection_Map (const Standard_Integer NbBuckets = 1,
|
||||
const Handle(NCollection_BaseAllocator)& theAllocator = 0L) :
|
||||
NCollection_BaseMap (NbBuckets, Standard_True, theAllocator) {}
|
||||
|
||||
//! Copy constructor
|
||||
NCollection_Map (const NCollection_Map& theOther) :
|
||||
|
@@ -108,11 +108,9 @@ public:
|
||||
public:
|
||||
// ---------- PUBLIC METHODS ------------
|
||||
|
||||
//! Empty constructor.
|
||||
NCollection_Sequence() : NCollection_BaseSequence(Handle(NCollection_BaseAllocator)()) {}
|
||||
|
||||
//! Constructor
|
||||
explicit NCollection_Sequence (const Handle(NCollection_BaseAllocator)& theAllocator) : NCollection_BaseSequence(theAllocator) {}
|
||||
NCollection_Sequence(const Handle(NCollection_BaseAllocator)& theAllocator=0L) :
|
||||
NCollection_BaseSequence(theAllocator) {}
|
||||
|
||||
//! Copy constructor
|
||||
NCollection_Sequence (const NCollection_Sequence& theOther) :
|
||||
|
@@ -49,7 +49,7 @@ template <class TheItemType> class NCollection_SparseArray
|
||||
public:
|
||||
|
||||
//! Constructor; accepts size of blocks
|
||||
explicit NCollection_SparseArray (Standard_Size theIncrement)
|
||||
NCollection_SparseArray (Standard_Size theIncrement)
|
||||
: NCollection_SparseArrayBase(sizeof(TheItemType),theIncrement)
|
||||
{
|
||||
}
|
||||
|
@@ -50,21 +50,21 @@ public:
|
||||
/*! Creates an object using default Open CASCADE allocation mechanism, i.e. which uses
|
||||
Standard::Allocate() and Standard::Free() underneath.
|
||||
*/
|
||||
NCollection_StdAllocator()
|
||||
NCollection_StdAllocator() throw()
|
||||
{ myAlloc = NCollection_BaseAllocator::CommonBaseAllocator(); }
|
||||
|
||||
//! Constructor.
|
||||
/*! Saves \a theAlloc as an underlying allocator instance.*/
|
||||
NCollection_StdAllocator( const Handle(NCollection_BaseAllocator)& theAlloc)
|
||||
NCollection_StdAllocator( const Handle(NCollection_BaseAllocator)& theAlloc) throw()
|
||||
{ myAlloc = theAlloc; }
|
||||
|
||||
//! Copy constructor.
|
||||
/*! Copies Allocator() from \a Y.*/
|
||||
template<typename U> NCollection_StdAllocator( const NCollection_StdAllocator<U>& Y)
|
||||
template<typename U> NCollection_StdAllocator( const NCollection_StdAllocator<U>& Y) throw()
|
||||
{ myAlloc = Y.Allocator(); }
|
||||
|
||||
//! Assignment operator
|
||||
template<typename U> NCollection_StdAllocator& operator= (const NCollection_StdAllocator<U>& Y)
|
||||
template<typename U> NCollection_StdAllocator& operator= (const NCollection_StdAllocator<U>& Y) throw()
|
||||
{ myAlloc = Y.Allocator(); return *this; }
|
||||
|
||||
//! Returns an object address.
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
void deallocate( pointer p, size_type ) { myAlloc->Free( p ); }
|
||||
|
||||
//! Returns the largest value for which method allocate might succeed.
|
||||
size_type max_size() const
|
||||
size_type max_size() const throw()
|
||||
{
|
||||
size_type aMax = static_cast<size_type>( -1 ) / sizeof( value_type );
|
||||
return aMax;
|
||||
@@ -138,24 +138,24 @@ public:
|
||||
/*! Creates an object using default Open CASCADE allocation mechanism, i.e. which uses
|
||||
Standard::Allocate() and Standard::Free() underneath.
|
||||
*/
|
||||
NCollection_StdAllocator()
|
||||
NCollection_StdAllocator() throw()
|
||||
{ myAlloc = NCollection_BaseAllocator::CommonBaseAllocator(); }
|
||||
|
||||
//! Constructor.
|
||||
/*! Saves \a theAlloc as an underlying allocator instance.*/
|
||||
NCollection_StdAllocator( const Handle(NCollection_BaseAllocator)& theAlloc)
|
||||
NCollection_StdAllocator( const Handle(NCollection_BaseAllocator)& theAlloc) throw()
|
||||
{ myAlloc = theAlloc; }
|
||||
|
||||
//! Constructor.
|
||||
/*! Copies Allocator() from \a X.*/
|
||||
NCollection_StdAllocator( const NCollection_StdAllocator& X) { myAlloc = X.myAlloc; }
|
||||
NCollection_StdAllocator( const NCollection_StdAllocator& X) throw() { myAlloc = X.myAlloc; }
|
||||
|
||||
//! Returns an underlying NCollection_BaseAllocator instance.
|
||||
/*! Returns an object specified in the constructor.*/
|
||||
const Handle(NCollection_BaseAllocator)& Allocator() const { return myAlloc; }
|
||||
|
||||
//! Assignment operator
|
||||
NCollection_StdAllocator& operator=(const NCollection_StdAllocator& X)
|
||||
NCollection_StdAllocator& operator=(const NCollection_StdAllocator& X) throw()
|
||||
{
|
||||
myAlloc = X.myAlloc;
|
||||
return *this;
|
||||
|
@@ -237,16 +237,18 @@ public:
|
||||
|
||||
// ---------- PUBLIC METHODS ----------
|
||||
|
||||
/**
|
||||
* Empty constructor.
|
||||
*/
|
||||
NCollection_UBTree() : myRoot(0L), myLastNode(0L), myAlloc (NCollection_BaseAllocator::CommonBaseAllocator()) {}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
explicit NCollection_UBTree (const Handle(NCollection_BaseAllocator)& theAllocator)
|
||||
: myRoot(0L), myLastNode(0L), myAlloc (!theAllocator.IsNull() ? theAllocator : NCollection_BaseAllocator::CommonBaseAllocator()) {}
|
||||
NCollection_UBTree
|
||||
(const Handle(NCollection_BaseAllocator)& theAllocator=0L)
|
||||
: myRoot(0L), myLastNode(0L)
|
||||
{
|
||||
if (theAllocator.IsNull())
|
||||
myAlloc = NCollection_BaseAllocator::CommonBaseAllocator();
|
||||
else
|
||||
myAlloc = theAllocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the tree with a new object and its bounding box.
|
||||
|
@@ -16,16 +16,12 @@
|
||||
#ifndef _NCollection_UtfIterator_H__
|
||||
#define _NCollection_UtfIterator_H__
|
||||
|
||||
#include <Standard_Handle.hxx>
|
||||
#include <Standard_TypeDef.hxx>
|
||||
|
||||
//! Template class for Unicode strings support.
|
||||
//!
|
||||
//! It defines an iterator and provide correct way to read multi-byte text (UTF-8 and UTF-16)
|
||||
//! and convert it from one to another.
|
||||
//! The current value of iterator is returned as UTF-32 Unicode symbol.
|
||||
//!
|
||||
//! Here and below term "Unicode symbol" is used as
|
||||
//! synonym of "Unicode code point".
|
||||
//! The current value of iterator returned as UTF-32 Unicode code.
|
||||
template<typename Type>
|
||||
class NCollection_UtfIterator
|
||||
{
|
||||
@@ -60,13 +56,20 @@ public:
|
||||
myCharIndex = 0;
|
||||
}
|
||||
|
||||
//! Pre-increment operator. Reads the next unicode symbol.
|
||||
//! Pre-increment operator. Reads the next unicode character.
|
||||
//! Notice - no protection against overrun!
|
||||
NCollection_UtfIterator& operator++()
|
||||
{
|
||||
myPosition = myPosNext;
|
||||
++myCharIndex;
|
||||
readNext (static_cast<const typename CharTypeChooser<Type>::type*>(0));
|
||||
switch (sizeof(Type))
|
||||
{
|
||||
case 1: readUTF8(); break;
|
||||
case 2: readUTF16(); break;
|
||||
case 4: // UTF-32
|
||||
default:
|
||||
myCharUtf32 = *myPosNext++;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -92,7 +95,7 @@ public:
|
||||
}
|
||||
|
||||
//! Dereference operator.
|
||||
//! @return the UTF-32 codepoint of the symbol currently pointed by iterator.
|
||||
//! @return the UTF-32 codepoint of the character currently pointed by iterator.
|
||||
Standard_Utf32Char operator*() const
|
||||
{
|
||||
return myCharUtf32;
|
||||
@@ -108,7 +111,6 @@ public:
|
||||
const Type* BufferNext() const { return myPosNext; }
|
||||
|
||||
//! @return the index displacement from iterator intialization
|
||||
//! (first symbol has index 0)
|
||||
Standard_Integer Index() const
|
||||
{
|
||||
return myCharIndex;
|
||||
@@ -159,61 +161,25 @@ public:
|
||||
|
||||
//! @return the advance in TypeWrite chars needed to store current symbol
|
||||
template<typename TypeWrite>
|
||||
inline Standard_Integer AdvanceBytesUtf() const
|
||||
{
|
||||
return advanceBytes(static_cast<const typename CharTypeChooser<TypeWrite>::type*>(0));
|
||||
}
|
||||
Standard_Integer AdvanceBytesUtf() const;
|
||||
|
||||
//! Fill the UTF-** buffer within current Unicode symbol.
|
||||
//! Use method AdvanceUtf**() to allocate buffer with enough size.
|
||||
//! @param theBuffer buffer to fill
|
||||
//! @return new buffer position (for next char)
|
||||
template<typename TypeWrite>
|
||||
inline TypeWrite* GetUtf (TypeWrite* theBuffer) const
|
||||
{
|
||||
return (TypeWrite*)(getUtf (reinterpret_cast<typename CharTypeChooser<TypeWrite>::type*>(theBuffer)));
|
||||
}
|
||||
TypeWrite* GetUtf (TypeWrite* theBuffer) const;
|
||||
|
||||
private:
|
||||
|
||||
//! Helper template class dispatching its argument class
|
||||
//! to the equivalent (by size) character (Unicode code unit) type.
|
||||
//! The code unit type is defined as nested typedef "type".
|
||||
//!
|
||||
//! In practice this is relevant for wchar_t type:
|
||||
//! typename CharTypeChooser<wchar_t>::type resolves to
|
||||
//! Standard_Utf16Char on Windows and to Standard_Utf32Char on Linux.
|
||||
template <typename TypeChar>
|
||||
class CharTypeChooser :
|
||||
public opencascade::std::conditional< sizeof(TypeChar) == 1, Standard_Utf8Char,
|
||||
typename opencascade::std::conditional< sizeof(TypeChar) == 2, Standard_Utf16Char,
|
||||
typename opencascade::std::conditional< sizeof(TypeChar) == 4, Standard_Utf32Char, void >::type >::type >
|
||||
{
|
||||
};
|
||||
|
||||
//! Helper function for reading a single Unicode symbol from the UTF-8 string.
|
||||
//! Helper function for reading a single UTF8 character from the string.
|
||||
//! Updates internal state appropriately.
|
||||
void readUTF8();
|
||||
|
||||
//! Helper function for reading a single Unicode symbol from the UTF-16 string.
|
||||
//! Helper function for reading a single UTF16 character from the string.
|
||||
//! Updates internal state appropriately.
|
||||
void readUTF16();
|
||||
|
||||
//! Helper overload methods to dispatch reading function depending on code unit size
|
||||
void readNext (const Standard_Utf8Char*) { readUTF8(); }
|
||||
void readNext (const Standard_Utf16Char*) { readUTF16(); }
|
||||
void readNext (const Standard_Utf32Char*) { myCharUtf32 = *myPosNext++; }
|
||||
|
||||
//! Helper overload methods to dispatch advance function depending on code unit size
|
||||
Standard_Integer advanceBytes (const Standard_Utf8Char*) const { return AdvanceBytesUtf8(); }
|
||||
Standard_Integer advanceBytes (const Standard_Utf16Char*) const { return AdvanceBytesUtf16(); }
|
||||
Standard_Integer advanceBytes (const Standard_Utf32Char*) const { return AdvanceBytesUtf32(); }
|
||||
|
||||
//! Helper overload methods to dispatch getter function depending on code unit size
|
||||
Standard_Utf8Char* getUtf (Standard_Utf8Char* theBuffer) const { return GetUtf8 (theBuffer); }
|
||||
Standard_Utf16Char* getUtf (Standard_Utf16Char* theBuffer) const { return GetUtf16(theBuffer); }
|
||||
Standard_Utf32Char* getUtf (Standard_Utf32Char* theBuffer) const { return GetUtf32(theBuffer); }
|
||||
|
||||
private: //! @name unicode magic numbers
|
||||
|
||||
static const unsigned char UTF8_BYTES_MINUS_ONE[256];
|
||||
@@ -233,10 +199,10 @@ private: //! @name unicode magic numbers
|
||||
|
||||
private: //! @name private fields
|
||||
|
||||
const Type* myPosition; //!< buffer position of the first element in the current symbol
|
||||
const Type* myPosNext; //!< buffer position of the first element in the next symbol
|
||||
const Type* myPosition; //!< buffer position of the first element in the current character
|
||||
const Type* myPosNext; //!< buffer position of the first element in the next character
|
||||
Standard_Integer myCharIndex; //!< index displacement from iterator intialization
|
||||
Standard_Utf32Char myCharUtf32; //!< Unicode symbol stored at the current buffer position
|
||||
Standard_Utf32Char myCharUtf32; //!< character stored at the current buffer position
|
||||
|
||||
};
|
||||
|
||||
|
@@ -317,3 +317,35 @@ Standard_Utf32Char* NCollection_UtfIterator<Type>::GetUtf32 (Standard_Utf32Char*
|
||||
*theBuffer++ = myCharUtf32;
|
||||
return theBuffer;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : AdvanceBytesUtf
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template<typename Type> template<typename TypeWrite> inline
|
||||
Standard_Integer NCollection_UtfIterator<Type>::AdvanceBytesUtf() const
|
||||
{
|
||||
switch (sizeof(TypeWrite))
|
||||
{
|
||||
case sizeof(Standard_Utf8Char): return AdvanceBytesUtf8();
|
||||
case sizeof(Standard_Utf16Char): return AdvanceBytesUtf16();
|
||||
case sizeof(Standard_Utf32Char): return AdvanceBytesUtf32();
|
||||
default: return 0; // invalid case
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetUtf
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template<typename Type> template<typename TypeWrite> inline
|
||||
TypeWrite* NCollection_UtfIterator<Type>::GetUtf (TypeWrite* theBuffer) const
|
||||
{
|
||||
switch (sizeof(TypeWrite))
|
||||
{
|
||||
case sizeof(Standard_Utf8Char): return (TypeWrite* )GetUtf8 ((Standard_Utf8UChar* )theBuffer);
|
||||
case sizeof(Standard_Utf16Char): return (TypeWrite* )GetUtf16((Standard_Utf16Char* )theBuffer);
|
||||
case sizeof(Standard_Utf32Char): return (TypeWrite* )GetUtf32((Standard_Utf32Char* )theBuffer);
|
||||
default: return NULL; // invalid case
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,9 @@
|
||||
#ifndef _NCollection_UtfString_H__
|
||||
#define _NCollection_UtfString_H__
|
||||
|
||||
#include <NCollection_UtfIterator.hxx>
|
||||
#include "NCollection_UtfIterator.hxx"
|
||||
|
||||
#include <Standard.hxx>
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
@@ -27,9 +29,6 @@
|
||||
//!
|
||||
//! Notice that changing the string is not allowed
|
||||
//! and any modifications should produce new string.
|
||||
//!
|
||||
//! In comments to this class, terms "Unicode symbol" is used as
|
||||
//! synonym of "Unicode code point".
|
||||
template<typename Type>
|
||||
class NCollection_UtfString
|
||||
{
|
||||
@@ -41,7 +40,7 @@ public:
|
||||
return NCollection_UtfIterator<Type> (myString);
|
||||
}
|
||||
|
||||
//! @return the size of the buffer in bytes, excluding NULL-termination symbol
|
||||
//! @return the size of the buffer, excluding NULL-termination symbol
|
||||
Standard_Integer Size() const
|
||||
{
|
||||
return mySize;
|
||||
@@ -61,8 +60,7 @@ public:
|
||||
|
||||
//! Retrieve string buffer at specified position.
|
||||
//! Warning! This is a slow access. Iterator should be used for consecutive parsing.
|
||||
//! @param theCharIndex the index of the symbol, should be less than Length()
|
||||
//! (first symbol of the string has index 0)
|
||||
//! @param theCharIndex the index of the symbol, should be lesser than Length()
|
||||
//! @return the pointer to the symbol
|
||||
const Type* GetCharBuffer (const Standard_Integer theCharIndex) const;
|
||||
|
||||
@@ -80,72 +78,45 @@ public:
|
||||
//! @param theCopy string to copy.
|
||||
NCollection_UtfString (const NCollection_UtfString& theCopy);
|
||||
|
||||
#ifndef OCCT_NO_RVALUE_REFERENCE
|
||||
//! Move constructor
|
||||
NCollection_UtfString (NCollection_UtfString&& theOther);
|
||||
#endif
|
||||
|
||||
//! Copy constructor from UTF-8 string.
|
||||
//! @param theCopyUtf8 UTF-8 string to copy
|
||||
//! @param theLength optional length limit in Unicode symbols (NOT bytes!)
|
||||
//! The string is copied till NULL symbol or, if theLength >0,
|
||||
//! till either NULL or theLength-th symbol (which comes first).
|
||||
//! Copy constructor from NULL-terminated UTF-8 string.
|
||||
//! @param theCopyUtf8 NULL-terminated UTF-8 string to copy
|
||||
//! @param theLength the length limit in Unicode symbols (NOT bytes!)
|
||||
NCollection_UtfString (const char* theCopyUtf8,
|
||||
const Standard_Integer theLength = -1);
|
||||
|
||||
//! Copy constructor from UTF-16 string.
|
||||
//! @param theCopyUtf16 UTF-16 string to copy
|
||||
//! Copy constructor from NULL-terminated UTF-16 string.
|
||||
//! @param theCopyUtf16 NULL-terminated UTF-16 string to copy
|
||||
//! @param theLength the length limit in Unicode symbols (NOT bytes!)
|
||||
//! The string is copied till NULL symbol or, if theLength >0,
|
||||
//! till either NULL or theLength-th symbol (which comes first).
|
||||
NCollection_UtfString (const Standard_Utf16Char* theCopyUtf16,
|
||||
const Standard_Integer theLength = -1);
|
||||
|
||||
//! Copy constructor from UTF-32 string.
|
||||
//! @param theCopyUtf32 UTF-32 string to copy
|
||||
//! Copy constructor from NULL-terminated UTF-32 string.
|
||||
//! @param theCopyUtf32 NULL-terminated UTF-32 string to copy
|
||||
//! @param theLength the length limit in Unicode symbols (NOT bytes!)
|
||||
//! The string is copied till NULL symbol or, if theLength >0,
|
||||
//! till either NULL or theLength-th symbol (which comes first).
|
||||
NCollection_UtfString (const Standard_Utf32Char* theCopyUtf32,
|
||||
const Standard_Integer theLength = -1);
|
||||
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) || (defined(_MSC_VER) && _MSC_VER >= 1900)
|
||||
//! Copy constructor from wide UTF string.
|
||||
//! @param theCopyUtfWide wide UTF string to copy
|
||||
//! Copy constructor from NULL-terminated wide UTF string.
|
||||
//! @param theCopyUtfWide NULL-terminated wide UTF string to copy
|
||||
//! @param theLength the length limit in Unicode symbols (NOT bytes!)
|
||||
//! The string is copied till NULL symbol or, if theLength >0,
|
||||
//! till either NULL or theLength-th symbol (which comes first).
|
||||
//!
|
||||
//! This constructor is undefined if Standard_WideChar is the same type as Standard_Utf16Char.
|
||||
NCollection_UtfString (const Standard_WideChar* theCopyUtfWide,
|
||||
const Standard_Integer theLength = -1);
|
||||
#endif
|
||||
|
||||
//! Copy from Unicode string in UTF-8, UTF-16, or UTF-32 encoding,
|
||||
//! determined by size of TypeFrom character type.
|
||||
//! @param theStringUtf Unicode string
|
||||
//! Copy from NULL-terminated Unicode string.
|
||||
//! @param theStringUtf NULL-terminated Unicode string
|
||||
//! @param theLength the length limit in Unicode symbols
|
||||
//! The string is copied till NULL symbol or, if theLength >0,
|
||||
//! till either NULL or theLength-th symbol (which comes first).
|
||||
template <typename TypeFrom>
|
||||
inline void FromUnicode (const TypeFrom* theStringUtf,
|
||||
const Standard_Integer theLength = -1)
|
||||
{
|
||||
NCollection_UtfIterator<TypeFrom> anIterRead (theStringUtf);
|
||||
if (*anIterRead == 0)
|
||||
{
|
||||
// special case
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
fromUnicodeImpl (theStringUtf, theLength, anIterRead);
|
||||
}
|
||||
void FromUnicode (const TypeFrom* theStringUtf,
|
||||
const Standard_Integer theLength = -1);
|
||||
|
||||
//! Copy from multibyte string in current system locale.
|
||||
//! @param theString multibyte string
|
||||
//! Copy from NULL-terminated multibyte string in system locale.
|
||||
//! You should avoid this function unless extreme necessity.
|
||||
//! @param theString NULL-terminated multibyte string
|
||||
//! @param theLength the length limit in Unicode symbols
|
||||
//! The string is copied till NULL symbol or, if theLength >0,
|
||||
//! till either NULL or theLength-th symbol (which comes first).
|
||||
void FromLocale (const char* theString,
|
||||
const Standard_Integer theLength = -1);
|
||||
|
||||
@@ -182,7 +153,8 @@ public:
|
||||
//! @return copy in wide format (UTF-16 on Windows and UTF-32 on Linux)
|
||||
const NCollection_UtfString<Standard_WideChar> ToUtfWide() const;
|
||||
|
||||
//! Converts the string into string in the current system locale.
|
||||
//! Converts the string into multibyte string.
|
||||
//! You should avoid this function unless extreme necessity.
|
||||
//! @param theBuffer output buffer
|
||||
//! @param theSizeBytes buffer size in bytes
|
||||
//! @return true on success
|
||||
@@ -201,18 +173,7 @@ public:
|
||||
public: //! @name assign operators
|
||||
|
||||
//! Copy from another string.
|
||||
const NCollection_UtfString& Assign (const NCollection_UtfString& theOther);
|
||||
|
||||
//! Exchange the data of two strings (without reallocating memory).
|
||||
void Swap (NCollection_UtfString& theOther);
|
||||
|
||||
//! Copy from another string.
|
||||
const NCollection_UtfString& operator= (const NCollection_UtfString& theOther) { return Assign (theOther); }
|
||||
|
||||
#ifndef OCCT_NO_RVALUE_REFERENCE
|
||||
//! Move assignment operator.
|
||||
NCollection_UtfString& operator= (NCollection_UtfString&& theOther) { Swap (theOther); return *this; }
|
||||
#endif
|
||||
const NCollection_UtfString& operator= (const NCollection_UtfString& theOther);
|
||||
|
||||
//! Copy from UTF-8 NULL-terminated string.
|
||||
const NCollection_UtfString& operator= (const char* theStringUtf8);
|
||||
@@ -249,50 +210,16 @@ public: //! @name compare operators
|
||||
|
||||
private: //! @name low-level methods
|
||||
|
||||
//! Implementation of copy routine for string of the same type
|
||||
void fromUnicodeImpl (const Type* theStringUtf, const Standard_Integer theLength, NCollection_UtfIterator<Type>& theIterator)
|
||||
{
|
||||
Type* anOldBuffer = myString; // necessary in case of self-copying
|
||||
|
||||
// advance to the end
|
||||
const Standard_Integer aLengthMax = (theLength > 0) ? theLength : IntegerLast();
|
||||
for(; *theIterator != 0 && theIterator.Index() < aLengthMax; ++theIterator) {}
|
||||
|
||||
mySize = Standard_Integer((Standard_Byte* )theIterator.BufferHere() - (Standard_Byte* )theStringUtf);
|
||||
myLength = theIterator.Index();
|
||||
myString = strAlloc (mySize);
|
||||
strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theStringUtf, mySize);
|
||||
|
||||
strFree (anOldBuffer);
|
||||
}
|
||||
|
||||
//! Implementation of copy routine for string of other types
|
||||
//! Compute advance for specified string.
|
||||
//! @param theStringUtf pointer to the NULL-terminated Unicode string
|
||||
//! @param theLengthMax length limit (to cut the string), set to -1 to compute up to NULL-termination symbol
|
||||
//! @param theSizeBytes advance in bytes (out)
|
||||
//! @param theLength string length (out)
|
||||
template<typename TypeFrom>
|
||||
void fromUnicodeImpl (typename opencascade::std::enable_if<! opencascade::std::is_same<Type, TypeFrom>::value, const TypeFrom*>::type theStringUtf,
|
||||
const Standard_Integer theLength, NCollection_UtfIterator<TypeFrom>& theIterator)
|
||||
{
|
||||
Type* anOldBuffer = myString; // necessary in case of self-copying
|
||||
|
||||
mySize = 0;
|
||||
const Standard_Integer aLengthMax = (theLength > 0) ? theLength : IntegerLast();
|
||||
for (; *theIterator != 0 && theIterator.Index() < aLengthMax; ++theIterator)
|
||||
{
|
||||
mySize += theIterator.template AdvanceBytesUtf<Type>();
|
||||
}
|
||||
myLength = theIterator.Index();
|
||||
|
||||
myString = strAlloc (mySize);
|
||||
|
||||
// copy string
|
||||
theIterator.Init (theStringUtf);
|
||||
Type* anIterWrite = myString;
|
||||
for (; *theIterator != 0 && theIterator.Index() < myLength; ++theIterator)
|
||||
{
|
||||
anIterWrite = theIterator.GetUtf (anIterWrite);
|
||||
}
|
||||
|
||||
strFree (anOldBuffer);
|
||||
}
|
||||
static void strGetAdvance (const TypeFrom* theStringUtf,
|
||||
const Standard_Integer theLengthMax,
|
||||
Standard_Integer& theSizeBytes,
|
||||
Standard_Integer& theLength);
|
||||
|
||||
//! Allocate NULL-terminated string buffer.
|
||||
static Type* strAlloc (const Standard_Size theSizeBytes)
|
||||
|
@@ -13,6 +13,53 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
// =======================================================================
|
||||
// function : strGetAdvance
|
||||
// purpose : Compute advance for specified string.
|
||||
// =======================================================================
|
||||
template<typename TypeTo> template<typename TypeFrom> inline
|
||||
void NCollection_UtfString<TypeTo>::strGetAdvance (const TypeFrom* theStringUtf,
|
||||
const Standard_Integer theLengthMax,
|
||||
Standard_Integer& theSizeBytes,
|
||||
Standard_Integer& theLength)
|
||||
{
|
||||
theSizeBytes = 0;
|
||||
theLength = 0;
|
||||
NCollection_UtfIterator<TypeFrom> anIter (theStringUtf);
|
||||
const Standard_Integer aLengthMax = (theLengthMax > 0) ? theLengthMax : IntegerLast();
|
||||
switch (sizeof(TypeTo))
|
||||
{
|
||||
case sizeof(Standard_Utf8Char):
|
||||
{
|
||||
for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter)
|
||||
{
|
||||
theSizeBytes += anIter.AdvanceBytesUtf8();
|
||||
}
|
||||
theLength = anIter.Index();
|
||||
return;
|
||||
}
|
||||
case sizeof(Standard_Utf16Char):
|
||||
{
|
||||
for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter)
|
||||
{
|
||||
theSizeBytes += anIter.AdvanceBytesUtf16();
|
||||
}
|
||||
theLength = anIter.Index();
|
||||
return;
|
||||
}
|
||||
case sizeof(Standard_Utf32Char):
|
||||
{
|
||||
for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter)
|
||||
{
|
||||
theSizeBytes += anIter.AdvanceBytesUtf32();
|
||||
}
|
||||
theLength = anIter.Index();
|
||||
return;
|
||||
}
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : GetChar
|
||||
// purpose :
|
||||
@@ -90,23 +137,6 @@ NCollection_UtfString<Type>::NCollection_UtfString (const NCollection_UtfString&
|
||||
strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theCopy.myString, mySize);
|
||||
}
|
||||
|
||||
#ifndef OCCT_NO_RVALUE_REFERENCE
|
||||
// =======================================================================
|
||||
// function : NCollection_UtfString
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template<typename Type> inline
|
||||
NCollection_UtfString<Type>::NCollection_UtfString (NCollection_UtfString&& theOther)
|
||||
: myString(theOther.myString),
|
||||
mySize (theOther.mySize),
|
||||
myLength(theOther.myLength)
|
||||
{
|
||||
theOther.myString = NULL;
|
||||
theOther.mySize = 0;
|
||||
theOther.myLength = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// =======================================================================
|
||||
// function : NCollection_UtfString
|
||||
// purpose :
|
||||
@@ -176,11 +206,11 @@ NCollection_UtfString<Type>::~NCollection_UtfString()
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Assign
|
||||
// function : operator=
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template<typename Type> inline
|
||||
const NCollection_UtfString<Type>& NCollection_UtfString<Type>::Assign (const NCollection_UtfString<Type>& theOther)
|
||||
const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const NCollection_UtfString<Type>& theOther)
|
||||
{
|
||||
if (this == &theOther)
|
||||
{
|
||||
@@ -196,23 +226,52 @@ const NCollection_UtfString<Type>& NCollection_UtfString<Type>::Assign (const NC
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Swap
|
||||
// function : FromUnicode
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
template<typename Type> inline
|
||||
void NCollection_UtfString<Type>::Swap (NCollection_UtfString<Type>& theOther)
|
||||
template<typename Type> template<typename TypeFrom>
|
||||
void NCollection_UtfString<Type>::FromUnicode (const TypeFrom* theStringUtf,
|
||||
const Standard_Integer theLength)
|
||||
{
|
||||
// Note: we could use std::swap() here, but prefer to not
|
||||
// have dependency on <algorithm> header at that level
|
||||
Type* aString = myString;
|
||||
const Standard_Integer aSize = mySize;
|
||||
const Standard_Integer aLength = myLength;
|
||||
myString = theOther.myString;
|
||||
mySize = theOther.mySize;
|
||||
myLength = theOther.myLength;
|
||||
theOther.myString = aString;
|
||||
theOther.mySize = aSize;
|
||||
theOther.myLength = aLength;
|
||||
Type* anOldBuffer = myString; // necessary in case of self-copying
|
||||
NCollection_UtfIterator<TypeFrom> anIterRead (theStringUtf);
|
||||
if (*anIterRead == 0)
|
||||
{
|
||||
// special case
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sizeof(TypeFrom)) // use switch() rather than if() to shut up msvc compiler
|
||||
{
|
||||
case sizeof(Type):
|
||||
{
|
||||
if (theLength > 0)
|
||||
{
|
||||
// optimized copy
|
||||
for(; *anIterRead != 0 && anIterRead.Index() < theLength; ++anIterRead) {}
|
||||
|
||||
mySize = Standard_Integer((Standard_Byte* )anIterRead.BufferHere() - (Standard_Byte* )theStringUtf);
|
||||
myLength = anIterRead.Index();
|
||||
myString = strAlloc (mySize);
|
||||
strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theStringUtf, mySize);
|
||||
strFree (anOldBuffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
strGetAdvance (theStringUtf, theLength, mySize, myLength);
|
||||
myString = strAlloc (mySize);
|
||||
// reset iterator
|
||||
anIterRead.Init (theStringUtf);
|
||||
Type* anIterWrite = myString;
|
||||
for (; *anIterRead != 0 && anIterRead.Index() < myLength; ++anIterRead)
|
||||
{
|
||||
anIterWrite = anIterRead.GetUtf (anIterWrite);
|
||||
}
|
||||
strFree (anOldBuffer);
|
||||
}
|
||||
|
||||
#if !defined(__ANDROID__)
|
||||
|
@@ -100,6 +100,8 @@ static int strcmp_joker(const char *Mask,const char *Name)
|
||||
void OSD_DirectoryIterator::Next(){
|
||||
int again = 1;
|
||||
struct stat stat_buf;
|
||||
char full_name[255];
|
||||
|
||||
myFlag = false; // Initialize to nothing found
|
||||
|
||||
do{
|
||||
@@ -117,8 +119,10 @@ struct stat stat_buf;
|
||||
// if (!strcmp(entry->d_name,"..")) continue; 2 directories.
|
||||
|
||||
// Is it a directory ?
|
||||
const TCollection_AsciiString aFullName = myPlace + "/" + ((struct dirent* )myEntry)->d_name;
|
||||
stat(aFullName.ToCString(), &stat_buf);
|
||||
|
||||
sprintf(full_name,"%s/%s",myPlace.ToCString(),
|
||||
((struct dirent *)myEntry)->d_name); // LD debug
|
||||
stat(full_name, &stat_buf);
|
||||
if (S_ISDIR(stat_buf.st_mode)) // Ensure me it's not a file
|
||||
if (strcmp_joker(myMask.ToCString(), ((struct dirent *)myEntry)->d_name)){
|
||||
// Does it follow mask ?
|
||||
|
@@ -176,6 +176,8 @@ static int strcmp_joker(char *fileMask,char *fileName)
|
||||
void OSD_FileIterator::Next(){
|
||||
int again = 1;
|
||||
struct stat stat_buf;
|
||||
char full_name[255];
|
||||
|
||||
myFlag = false; // Initialize to nothing found
|
||||
|
||||
do {
|
||||
@@ -193,8 +195,14 @@ struct stat stat_buf;
|
||||
if (!strcmp(((struct dirent *)myEntry)->d_name,"..")) continue;
|
||||
|
||||
// Is it a file ?
|
||||
const TCollection_AsciiString aFullName = myPlace + "/" + ((struct dirent* )myEntry)->d_name;
|
||||
stat(aFullName.ToCString(), &stat_buf);
|
||||
|
||||
sprintf(full_name,"%s/%s",myPlace.ToCString(),
|
||||
((struct dirent *)myEntry)->d_name); // LD debug
|
||||
#ifdef OCCT_DEBUG
|
||||
cout << "Place : " << myPlace << endl;
|
||||
cout << "FName : " << full_name << endl;
|
||||
#endif
|
||||
stat(full_name, &stat_buf);
|
||||
if (S_ISREG(stat_buf.st_mode)) // LD : Ensure me it's a regular file
|
||||
if (strcmp_joker(myMask.ToCString(), ((struct dirent *)myEntry)->d_name)){
|
||||
// Does it follow mask ?
|
||||
|
@@ -217,10 +217,8 @@ OSD_Host :: OSD_Host () {
|
||||
ZeroMemory (&ms, sizeof(ms));
|
||||
ZeroMemory (szHostName, sizeof(char) * (MAX_COMPUTERNAME_LENGTH + 1));
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// suppress GetVersionEx() deprecation warning
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#pragma warning(disable : 1478)
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
if (!GetVersionExW (&osVerInfo))
|
||||
|
@@ -24,11 +24,7 @@
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
OpenGl_BVHTreeSelector::OpenGl_BVHTreeSelector()
|
||||
: myIsProjectionParallel (Standard_True),
|
||||
myCamScaleInv (1.0),
|
||||
myDistCull (-1.0),
|
||||
myPixelSize (1.0),
|
||||
mySizeCull2 (-1.0)
|
||||
: myIsProjectionParallel (Standard_True)
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -48,8 +44,6 @@ 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;
|
||||
@@ -130,14 +124,11 @@ void OpenGl_BVHTreeSelector::SetViewVolume (const Handle(Graphic3d_Camera)& theC
|
||||
// function : SetViewportSize
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::SetViewportSize (Standard_Integer theViewportWidth,
|
||||
Standard_Integer theViewportHeight,
|
||||
Standard_Real theResolutionRatio)
|
||||
void OpenGl_BVHTreeSelector::SetViewportSize (const Standard_Integer theViewportWidth,
|
||||
const Standard_Integer theViewportHeight)
|
||||
{
|
||||
myViewportHeight = theViewportHeight;
|
||||
myViewportWidth = theViewportWidth;
|
||||
myPixelSize = Max (theResolutionRatio / theViewportHeight,
|
||||
theResolutionRatio / theViewportWidth);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -162,38 +153,10 @@ 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 (Standard_Real theDistance)
|
||||
{
|
||||
myDistCull = -1.0;
|
||||
if (!myIsProjectionParallel)
|
||||
{
|
||||
myDistCull = theDistance > 0.0 && !Precision::IsInfinite (theDistance)
|
||||
? theDistance
|
||||
: -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetCullingSize
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::SetCullingSize (Standard_Real theSize)
|
||||
{
|
||||
mySizeCull2 = -1.0;
|
||||
if (theSize > 0.0 && !Precision::IsInfinite (theSize))
|
||||
{
|
||||
mySizeCull2 = (myPixelSize * theSize) / myCamScaleInv;
|
||||
mySizeCull2 *= mySizeCull2;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : CacheClipPtsProjections
|
||||
// purpose :
|
||||
// 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
|
||||
// =======================================================================
|
||||
void OpenGl_BVHTreeSelector::CacheClipPtsProjections()
|
||||
{
|
||||
@@ -291,26 +254,5 @@ Standard_Boolean OpenGl_BVHTreeSelector::Intersect (const OpenGl_Vec3d& theMinPt
|
||||
}
|
||||
}
|
||||
|
||||
// distance culling - discard node if distance to it's bounding box from camera eye is less than specified culling distance
|
||||
if (myDistCull > 0.0)
|
||||
{
|
||||
// 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;
|
||||
if ((aSphereCenter - myCamEye).Modulus() - aSphereRadius > myDistCull)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
// size culling - discard node if diagonal of it's bounding box is less than specified culling size
|
||||
if (mySizeCull2 > 0.0)
|
||||
{
|
||||
if ((theMaxPt - theMinPt).SquareModulus() < mySizeCull2)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
@@ -33,19 +33,7 @@ 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 (Standard_Integer theViewportWidth,
|
||||
Standard_Integer theViewportHeight,
|
||||
Standard_Real theResolutionRatio);
|
||||
|
||||
//! Setup distance culling.
|
||||
Standard_EXPORT void SetCullingDistance (Standard_Real theDistance);
|
||||
|
||||
//! Setup size culling.
|
||||
Standard_EXPORT void SetCullingSize (Standard_Real theSize);
|
||||
|
||||
//! 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();
|
||||
Standard_EXPORT void SetViewportSize (const Standard_Integer theViewportWidth, const Standard_Integer theViewportHeight);
|
||||
|
||||
//! Detects if AABB overlaps view volume using separating axis theorem (SAT).
|
||||
//! @param theMinPt [in] maximum point of AABB.
|
||||
@@ -54,6 +42,10 @@ public:
|
||||
Standard_EXPORT Standard_Boolean Intersect (const OpenGl_Vec3d& theMinPt,
|
||||
const OpenGl_Vec3d& theMaxPt) 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();
|
||||
|
||||
//! Return the camera definition.
|
||||
const Handle(Graphic3d_Camera)& Camera() const { return myCamera; }
|
||||
|
||||
@@ -147,13 +139,6 @@ 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 myDistCull; //!< culling distance
|
||||
Standard_Real myPixelSize; //!< pixel size for size culling
|
||||
Standard_Real mySizeCull2; //!< squared culling size
|
||||
|
||||
};
|
||||
|
||||
#endif // _OpenGl_BVHTreeSelector_HeaderFile
|
||||
|
@@ -73,7 +73,7 @@ namespace
|
||||
aContext->ShaderManager()->UpdateClippingState();
|
||||
|
||||
glClear (GL_STENCIL_BUFFER_BIT);
|
||||
const bool aColorMaskBack = aContext->SetColorMask (false);
|
||||
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
|
||||
// override aspects, disable culling
|
||||
theWorkspace->SetAspectFace (&theWorkspace->NoneCulling());
|
||||
@@ -116,7 +116,7 @@ namespace
|
||||
aContext->ShaderManager()->UpdateClippingState();
|
||||
|
||||
// render capping plane using the generated stencil mask
|
||||
aContext->SetColorMask (aColorMaskBack);
|
||||
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
if (theWorkspace->UseDepthWrite())
|
||||
{
|
||||
glDepthMask (GL_TRUE);
|
||||
|
@@ -188,7 +188,6 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
|
||||
myReadBuffer (0),
|
||||
myDrawBuffers (1),
|
||||
myDefaultVao (0),
|
||||
myColorMask (true),
|
||||
myIsGlDebugCtx (Standard_False),
|
||||
myResolution (Graphic3d_RenderingParams::THE_DEFAULT_RESOLUTION),
|
||||
myResolutionRatio (1.0f),
|
||||
@@ -3679,17 +3678,3 @@ void OpenGl_Context::DisableFeatures() const
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : SetColorMask
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Context::SetColorMask (bool theToWriteColor)
|
||||
{
|
||||
const GLboolean toWrite = theToWriteColor ? GL_TRUE : GL_FALSE;
|
||||
glColorMask (toWrite, toWrite, toWrite, toWrite);
|
||||
|
||||
const bool anOldValue = myColorMask;
|
||||
myColorMask = theToWriteColor;
|
||||
return anOldValue;
|
||||
}
|
||||
|
@@ -625,12 +625,6 @@ public: //! @name methods to alter or retrieve current state
|
||||
SetDrawBuffer (theBuffer);
|
||||
}
|
||||
|
||||
//! Return cached flag indicating writing into color buffer is enabled or disabled (glColorMask).
|
||||
bool ColorMask() const { return myColorMask; }
|
||||
|
||||
//! Enable/disable writing into color buffer (wrapper for glColorMask).
|
||||
Standard_EXPORT bool SetColorMask (bool theToWriteColor);
|
||||
|
||||
//! Return back face culling state.
|
||||
bool ToCullBackFaces() const { return myToCullBackFaces; }
|
||||
|
||||
@@ -912,7 +906,6 @@ private: //! @name fields tracking current state
|
||||
Standard_Integer myReadBuffer; //!< current read buffer
|
||||
OpenGl_DrawBuffers myDrawBuffers; //!< current draw buffers
|
||||
unsigned int myDefaultVao; //!< default Vertex Array Object
|
||||
Standard_Boolean myColorMask; //!< flag indicating writing into color buffer is enabled or disabled (glColorMask)
|
||||
Standard_Boolean myIsGlDebugCtx; //!< debug context initialization state
|
||||
TCollection_AsciiString myVendor; //!< Graphics Driver's vendor
|
||||
TColStd_PackedMapOfInteger myFilters[6]; //!< messages suppressing filter (for sources from GL_DEBUG_SOURCE_API_ARB to GL_DEBUG_SOURCE_OTHER_ARB)
|
||||
|
@@ -406,7 +406,7 @@ Standard_Integer OpenGl_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit
|
||||
switch (theType)
|
||||
{
|
||||
case Graphic3d_TypeOfLimit_MaxNbLights:
|
||||
return Graphic3d_ShaderProgram::THE_MAX_LIGHTS_DEFAULT;
|
||||
return OpenGLMaxLights;
|
||||
case Graphic3d_TypeOfLimit_MaxNbClipPlanes:
|
||||
return !aCtx.IsNull() ? aCtx->MaxClipPlanes() : 0;
|
||||
case Graphic3d_TypeOfLimit_MaxNbViews:
|
||||
|
@@ -48,6 +48,7 @@
|
||||
#include <TColStd_MapOfInteger.hxx>
|
||||
|
||||
class Aspect_Window;
|
||||
class Graphic3d_Vector;
|
||||
class Quantity_Color;
|
||||
class Graphic3d_Vertex;
|
||||
class TCollection_ExtendedString;
|
||||
|
@@ -489,15 +489,9 @@ void OpenGl_Layer::updateBVH() const
|
||||
void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const
|
||||
{
|
||||
updateBVH();
|
||||
if (myBVHPrimitives .Size() != 0
|
||||
|| myBVHPrimitivesTrsfPers.Size() != 0)
|
||||
{
|
||||
|
||||
OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector();
|
||||
aSelector.SetCullingDistance (myLayerSettings.CullingDistance());
|
||||
aSelector.SetCullingSize (myLayerSettings.CullingSize());
|
||||
aSelector.CacheClipPtsProjections();
|
||||
traverse (aSelector);
|
||||
}
|
||||
|
||||
const Standard_Integer aViewId = theWorkspace->View()->Identification();
|
||||
for (OpenGl_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
|
||||
@@ -522,8 +516,15 @@ void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace)
|
||||
// function : traverse
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
void OpenGl_Layer::traverse (const OpenGl_BVHTreeSelector& theSelector) const
|
||||
void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
|
||||
{
|
||||
// handle a case when all objects are infinite
|
||||
if (myBVHPrimitives .Size() == 0
|
||||
&& myBVHPrimitivesTrsfPers.Size() == 0)
|
||||
return;
|
||||
|
||||
theSelector.CacheClipPtsProjections();
|
||||
|
||||
opencascade::handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
|
||||
for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
|
||||
{
|
||||
@@ -594,8 +595,8 @@ void OpenGl_Layer::traverse (const OpenGl_BVHTreeSelector& theSelector) const
|
||||
else
|
||||
{
|
||||
Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode);
|
||||
const OpenGl_Structure* aStruct = isTrsfPers
|
||||
? myBVHPrimitivesTrsfPers.GetStructureById (aIdx)
|
||||
const OpenGl_Structure* aStruct =
|
||||
isTrsfPers ? myBVHPrimitivesTrsfPers.GetStructureById (aIdx)
|
||||
: myBVHPrimitives.GetStructureById (aIdx);
|
||||
aStruct->MarkAsNotCulled();
|
||||
if (aHead < 0)
|
||||
@@ -695,6 +696,7 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace,
|
||||
const Standard_Boolean hasLocalCS = !myLayerSettings.OriginTransformation().IsNull();
|
||||
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
|
||||
const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera();
|
||||
Handle(Graphic3d_Camera) aCameraBack;
|
||||
if (hasLocalCS)
|
||||
{
|
||||
// Apply local camera transformation.
|
||||
|
@@ -135,7 +135,7 @@ protected:
|
||||
void updateBVH() const;
|
||||
|
||||
//! Traverses through BVH tree to determine which structures are in view volume.
|
||||
void traverse (const OpenGl_BVHTreeSelector& theSelector) const;
|
||||
void traverse (OpenGl_BVHTreeSelector& theSelector) const;
|
||||
|
||||
//! Iterates through the hierarchical list of existing structures and renders them all.
|
||||
void renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const;
|
||||
|
@@ -26,117 +26,6 @@
|
||||
|
||||
#include <Graphic3d_GraphicDriver.hxx>
|
||||
|
||||
namespace
|
||||
{
|
||||
//! Auxiliary class extending sequence iterator with index.
|
||||
class OpenGl_IndexedLayerIterator : public OpenGl_SequenceOfLayers::Iterator
|
||||
{
|
||||
public:
|
||||
//! Main constructor.
|
||||
OpenGl_IndexedLayerIterator (const OpenGl_SequenceOfLayers& theSeq)
|
||||
: OpenGl_SequenceOfLayers::Iterator (theSeq),
|
||||
myIndex (theSeq.Lower()) {}
|
||||
|
||||
//! Return index of current position.
|
||||
Standard_Integer Index() const { return myIndex; }
|
||||
|
||||
//! Move to the next position.
|
||||
void Next()
|
||||
{
|
||||
OpenGl_SequenceOfLayers::Iterator::Next();
|
||||
++myIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
Standard_Integer myIndex;
|
||||
};
|
||||
|
||||
//! Iterator through layers with filter.
|
||||
class OpenGl_FilteredIndexedLayerIterator
|
||||
{
|
||||
public:
|
||||
//! Main constructor.
|
||||
OpenGl_FilteredIndexedLayerIterator (const OpenGl_SequenceOfLayers& theSeq,
|
||||
Standard_Integer theDefaultLayerIndex,
|
||||
Standard_Boolean theToDrawImmediate,
|
||||
OpenGl_LayerFilter theLayersToProcess)
|
||||
: myIter (theSeq),
|
||||
myDefaultLayerIndex (theDefaultLayerIndex),
|
||||
myLayersToProcess (theLayersToProcess),
|
||||
myToDrawImmediate (theToDrawImmediate)
|
||||
{
|
||||
next();
|
||||
}
|
||||
|
||||
//! Return true if iterator points to the valid value.
|
||||
bool More() const { return myIter.More(); }
|
||||
|
||||
//! Return layer at current position.
|
||||
const OpenGl_Layer& Value() const { return *myIter.Value(); }
|
||||
|
||||
//! Return index of current position.
|
||||
Standard_Integer Index() const { return myIter.Index(); }
|
||||
|
||||
//! Go to the next item.
|
||||
void Next()
|
||||
{
|
||||
myIter.Next();
|
||||
next();
|
||||
}
|
||||
|
||||
private:
|
||||
//! Look for the nearest item passing filters.
|
||||
void next()
|
||||
{
|
||||
for (; myIter.More(); myIter.Next())
|
||||
{
|
||||
if (myIter.Value()->IsImmediate() != myToDrawImmediate)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (myLayersToProcess)
|
||||
{
|
||||
case OpenGl_LF_All:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case OpenGl_LF_Upper:
|
||||
{
|
||||
if (myIter.Index() <= myDefaultLayerIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpenGl_LF_Bottom:
|
||||
{
|
||||
if (myIter.Index() >= myDefaultLayerIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpenGl_LF_Default:
|
||||
{
|
||||
if (myIter.Index() != myDefaultLayerIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
private:
|
||||
OpenGl_IndexedLayerIterator myIter;
|
||||
Standard_Integer myDefaultLayerIndex;
|
||||
OpenGl_LayerFilter myLayersToProcess;
|
||||
Standard_Boolean myToDrawImmediate;
|
||||
};
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : OpenGl_LayerList
|
||||
//purpose : Constructor
|
||||
@@ -334,10 +223,11 @@ void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure)
|
||||
}
|
||||
|
||||
// scan through layers and remove it
|
||||
for (OpenGl_IndexedLayerIterator anIts (myLayers); anIts.More(); anIts.Next())
|
||||
Standard_Integer aSeqId = 1;
|
||||
for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
|
||||
{
|
||||
OpenGl_Layer& aLayerEx = *anIts.ChangeValue();
|
||||
if (aSeqPos == anIts.Index())
|
||||
if (aSeqPos == aSeqId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -350,7 +240,7 @@ void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure* theStructure)
|
||||
--myImmediateNbStructures;
|
||||
}
|
||||
|
||||
if (anIts.Index() == myDefaultLayerIndex
|
||||
if (aSeqId == myDefaultLayerIndex
|
||||
&& theStructure->IsRaytracable())
|
||||
{
|
||||
++myModifStateOfRaytraceable;
|
||||
@@ -409,9 +299,10 @@ void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure* theStructure,
|
||||
}
|
||||
|
||||
// scan through layers and remove it
|
||||
for (OpenGl_IndexedLayerIterator anIts (myLayers); anIts.More(); anIts.Next())
|
||||
Standard_Integer aSeqId = 1;
|
||||
for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
|
||||
{
|
||||
if (aSeqPos == anIts.Index())
|
||||
if (aSeqPos == aSeqId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -420,7 +311,7 @@ void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure* theStructure,
|
||||
OpenGl_Layer& aLayerEx = *anIts.ChangeValue();
|
||||
if (aLayerEx.Remove (theStructure, aPriority, Standard_True))
|
||||
{
|
||||
if (anIts.Index() == myDefaultLayerIndex
|
||||
if (aSeqId == myDefaultLayerIndex
|
||||
&& theStructure->IsRaytracable())
|
||||
{
|
||||
++myModifStateOfRaytraceable;
|
||||
@@ -465,9 +356,10 @@ void OpenGl_LayerList::ChangePriority (const OpenGl_Structure* theStructure,
|
||||
return;
|
||||
}
|
||||
|
||||
for (OpenGl_IndexedLayerIterator anIts (myLayers); anIts.More(); anIts.Next())
|
||||
Standard_Integer aSeqId = 1;
|
||||
for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
|
||||
{
|
||||
if (aSeqPos == anIts.Index())
|
||||
if (aSeqPos == aSeqId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -520,12 +412,11 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
|
||||
OpenGl_FrameBuffer* theOitAccumFbo) const
|
||||
{
|
||||
// Remember global settings for glDepth function and write mask.
|
||||
OpenGl_GlobalLayerSettings aPrevSettings;
|
||||
OpenGl_GlobalLayerSettings aDefaultSettings;
|
||||
|
||||
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
|
||||
aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC, &aPrevSettings.DepthFunc);
|
||||
aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aPrevSettings.DepthMask);
|
||||
OpenGl_GlobalLayerSettings aDefaultSettings = aPrevSettings;
|
||||
aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC, &aDefaultSettings.DepthFunc);
|
||||
aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aDefaultSettings.DepthMask);
|
||||
|
||||
// Two render filters are used to support transparency draw. Opaque filter accepts
|
||||
// only non-transparent OpenGl elements of a layer and counts number of skipped
|
||||
@@ -545,78 +436,52 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
|
||||
myTransparentToProcess.Clear();
|
||||
|
||||
OpenGl_LayerStack::iterator aStackIter (myTransparentToProcess.Origin());
|
||||
Standard_Integer aClearDepthLayerPrev = -1, aClearDepthLayer = -1;
|
||||
const bool toPerformDepthPrepass = theWorkspace->View()->RenderingParams().ToEnableDepthPrepass
|
||||
&& aPrevSettings.DepthMask == GL_TRUE;
|
||||
for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, myDefaultLayerIndex, theToDrawImmediate, theLayersToProcess); aLayerIterStart.More();)
|
||||
Standard_Integer aSeqId = myLayers.Lower();
|
||||
bool toClearDepth = false;
|
||||
for (OpenGl_SequenceOfLayers::Iterator aLayerIter (myLayers); aLayerIter.More(); aLayerIter.Next(), ++aSeqId)
|
||||
{
|
||||
bool hasSkippedDepthLayers = false;
|
||||
for (int aPassIter = toPerformDepthPrepass ? 0 : 2; aPassIter < 3; ++aPassIter)
|
||||
if (theLayersToProcess == OpenGl_LF_Bottom)
|
||||
{
|
||||
if (aPassIter == 0)
|
||||
{
|
||||
aCtx->SetColorMask (false);
|
||||
aDefaultSettings.DepthFunc = aPrevSettings.DepthFunc;
|
||||
aDefaultSettings.DepthMask = GL_TRUE;
|
||||
if (aSeqId >= myDefaultLayerIndex) continue;
|
||||
}
|
||||
else if (aPassIter == 1)
|
||||
else if (theLayersToProcess == OpenGl_LF_Upper)
|
||||
{
|
||||
if (!hasSkippedDepthLayers)
|
||||
{
|
||||
continue;
|
||||
if (aSeqId <= myDefaultLayerIndex) continue;
|
||||
}
|
||||
aCtx->SetColorMask (true);
|
||||
aDefaultSettings = aPrevSettings;
|
||||
}
|
||||
else if (aPassIter == 2)
|
||||
else if (theLayersToProcess == OpenGl_LF_Default)
|
||||
{
|
||||
aCtx->SetColorMask (true);
|
||||
if (toPerformDepthPrepass)
|
||||
{
|
||||
aDefaultSettings.DepthFunc = GL_EQUAL;
|
||||
aDefaultSettings.DepthMask = GL_FALSE;
|
||||
}
|
||||
if (aSeqId != myDefaultLayerIndex) continue;
|
||||
}
|
||||
|
||||
OpenGl_FilteredIndexedLayerIterator aLayerIter (aLayerIterStart);
|
||||
for (; aLayerIter.More(); aLayerIter.Next())
|
||||
const OpenGl_Layer& aLayer = *aLayerIter.Value();
|
||||
if (aLayer.IsImmediate() != theToDrawImmediate)
|
||||
{
|
||||
const OpenGl_Layer& aLayer = aLayerIter.Value();
|
||||
continue;
|
||||
}
|
||||
else if (aLayer.NbStructures() < 1)
|
||||
{
|
||||
// Make sure to clear depth of previous layers even if layer has no structures.
|
||||
toClearDepth = toClearDepth || aLayer.LayerSettings().ToClearDepth();
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure to clear depth of previous layers even if layer has no structures
|
||||
if (aLayer.LayerSettings().ToClearDepth())
|
||||
// At this point the depth buffer may be set to clear by
|
||||
// previous configuration of layers or configuration of the
|
||||
// current layer. Additional rendering pass to handle transparent
|
||||
// elements of recently drawn layers require use of current depth
|
||||
// buffer so we put remaining layers for processing as one bunch before
|
||||
// erasing the depth buffer.
|
||||
if (toClearDepth
|
||||
|| aLayer.LayerSettings().ToClearDepth())
|
||||
{
|
||||
aClearDepthLayer = aLayerIter.Index();
|
||||
if (!myTransparentToProcess.IsEmpty())
|
||||
{
|
||||
renderTransparent (theWorkspace, aStackIter, aDefaultSettings, theReadDrawFbo, theOitAccumFbo);
|
||||
}
|
||||
if (aLayer.NbStructures() < 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (aClearDepthLayer > aClearDepthLayerPrev)
|
||||
{
|
||||
// At this point the depth buffer may be set to clear by previous configuration of layers or configuration of the current layer.
|
||||
// Additional rendering pass to handle transparent elements of recently drawn layers require use of current depth
|
||||
// buffer so we put remaining layers for processing as one bunch before erasing the depth buffer.
|
||||
if (aPassIter == 2)
|
||||
{
|
||||
aLayerIterStart = aLayerIter;
|
||||
}
|
||||
else
|
||||
{
|
||||
aClearDepthLayer = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (aPassIter == 0
|
||||
&& !aLayer.LayerSettings().ToRenderInDepthPrepass())
|
||||
{
|
||||
hasSkippedDepthLayers = true;
|
||||
continue;
|
||||
}
|
||||
else if (aPassIter == 1
|
||||
&& aLayer.LayerSettings().ToRenderInDepthPrepass())
|
||||
{
|
||||
continue;
|
||||
|
||||
toClearDepth = false;
|
||||
glDepthMask (GL_TRUE);
|
||||
glClear (GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// Render opaque OpenGl elements of a layer and count the number of skipped.
|
||||
@@ -626,33 +491,26 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
|
||||
|
||||
aLayer.Render (theWorkspace, aDefaultSettings);
|
||||
|
||||
if (aPassIter != 0
|
||||
&& myRenderOpaqueFilter->NbSkipped() > 0)
|
||||
if (myRenderOpaqueFilter->NbSkipped() > 0)
|
||||
{
|
||||
myTransparentToProcess.Push (&aLayer);
|
||||
}
|
||||
}
|
||||
if (aPassIter == 2
|
||||
&& !aLayerIter.More())
|
||||
{
|
||||
aLayerIterStart = aLayerIter;
|
||||
}
|
||||
}
|
||||
|
||||
// Before finishing process the remaining collected layers with transparency.
|
||||
if (!myTransparentToProcess.IsEmpty())
|
||||
{
|
||||
renderTransparent (theWorkspace, aStackIter, aPrevSettings, theReadDrawFbo, theOitAccumFbo);
|
||||
renderTransparent (theWorkspace, aStackIter, aDefaultSettings, theReadDrawFbo, theOitAccumFbo);
|
||||
}
|
||||
if (aClearDepthLayer > aClearDepthLayerPrev)
|
||||
|
||||
if (toClearDepth)
|
||||
{
|
||||
aClearDepthLayerPrev = aClearDepthLayer;
|
||||
glDepthMask (GL_TRUE);
|
||||
glClear (GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
aCtx->core11fwd->glDepthMask (aPrevSettings.DepthMask);
|
||||
aCtx->core11fwd->glDepthFunc (aPrevSettings.DepthFunc);
|
||||
aCtx->core11fwd->glDepthMask (aDefaultSettings.DepthMask);
|
||||
aCtx->core11fwd->glDepthFunc (aDefaultSettings.DepthFunc);
|
||||
|
||||
theWorkspace->SetRenderFilter (aPrevFilter);
|
||||
}
|
||||
|
@@ -448,6 +448,13 @@ void OpenGl_PrimitiveArray::drawEdges (const OpenGl_Vec4& theEdgeCo
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (aGlContext->core11 != NULL)
|
||||
{
|
||||
glDisable (GL_LIGHTING);
|
||||
}
|
||||
#endif
|
||||
|
||||
const OpenGl_AspectLine* anAspectLineOld = theWorkspace->SetAspectLine (theWorkspace->AspectFace()->AspectEdge());
|
||||
const OpenGl_AspectLine* anAspect = theWorkspace->ApplyAspectLine();
|
||||
|
||||
@@ -467,13 +474,6 @@ void OpenGl_PrimitiveArray::drawEdges (const OpenGl_Vec4& theEdgeCo
|
||||
&& aGlContext->ActiveProgram()->HasTessellationStage()
|
||||
? GL_PATCHES
|
||||
: myDrawMode;
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (aGlContext->ActiveProgram().IsNull()
|
||||
&& aGlContext->core11 != NULL)
|
||||
{
|
||||
glDisable (GL_LIGHTING);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// OCC22236 NOTE: draw edges for all situations:
|
||||
/// 1) draw elements with GL_LINE style as edges from myPArray->bufferVBO[VBOEdges] indices array
|
||||
@@ -736,8 +736,7 @@ void OpenGl_PrimitiveArray::Render (const Handle(OpenGl_Workspace)& theWorkspace
|
||||
&& myVboAttribs->HasColorAttribute();
|
||||
const Standard_Boolean isLightOn = !anAspectFace->IsNoLighting()
|
||||
&& !myVboAttribs.IsNull()
|
||||
&& myVboAttribs->HasNormalAttribute()
|
||||
&& aCtx->ColorMask();
|
||||
&& myVboAttribs->HasNormalAttribute();
|
||||
|
||||
// Temporarily disable environment mapping
|
||||
Handle(OpenGl_TextureSet) aTextureBack;
|
||||
|
@@ -33,6 +33,9 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
|
||||
namespace
|
||||
{
|
||||
|
||||
//! Clipping planes limit (see the same definition in Declarations.glsl).
|
||||
static const Standard_Size THE_MAX_CLIP_PLANES = 8;
|
||||
|
||||
#define EOL "\n"
|
||||
|
||||
//! Definition of TexCoord varying.
|
||||
@@ -593,30 +596,27 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
|
||||
return;
|
||||
}
|
||||
|
||||
if (myContext->core11 != NULL)
|
||||
{
|
||||
GLenum aLightGlId = GL_LIGHT0;
|
||||
OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
|
||||
const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
|
||||
if (myLightSourceState.LightSources() != NULL)
|
||||
for (OpenGl_ListOfLight::Iterator aLightIt (*myLightSourceState.LightSources()); aLightIt.More(); aLightIt.Next())
|
||||
{
|
||||
for (Graphic3d_ListOfCLight::Iterator aLightIt (*myLightSourceState.LightSources()); aLightIt.More(); aLightIt.Next())
|
||||
{
|
||||
const Graphic3d_CLight& aLight = aLightIt.Value();
|
||||
const OpenGl_Light& aLight = aLightIt.Value();
|
||||
if (aLight.Type == Graphic3d_TOLS_AMBIENT)
|
||||
{
|
||||
anAmbient += aLight.Color;
|
||||
continue;
|
||||
}
|
||||
else if (aLightGlId > GL_LIGHT7) // only 8 lights in FFP...
|
||||
else if (aLightGlId > GL_LIGHT7) // OpenGLMaxLights - only 8 lights in OpenGL...
|
||||
{
|
||||
myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
|
||||
"Warning: light sources limit (8) has been exceeded within Fixed-function pipeline.");
|
||||
continue;
|
||||
}
|
||||
|
||||
bindLight (aLight, aLightGlId, aModelView, myContext);
|
||||
bindLight (aLightIt.Value(), aLightGlId, aModelView, myContext);
|
||||
++aLightGlId;
|
||||
}
|
||||
}
|
||||
|
||||
// apply accumulated ambient color
|
||||
anAmbient.a() = 1.0f;
|
||||
@@ -637,41 +637,29 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
|
||||
{
|
||||
::glDisable (aLightGlId);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
const Standard_Integer aNbLightsMax = theProgram->NbLightsMax();
|
||||
const GLint anAmbientLoc = theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT);
|
||||
if (aNbLightsMax == 0
|
||||
&& anAmbientLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
|
||||
for (Standard_Integer aLightIt = 0; aLightIt < OpenGLMaxLights; ++aLightIt)
|
||||
{
|
||||
return;
|
||||
myLightTypeArray[aLightIt].Type = -1;
|
||||
}
|
||||
|
||||
if (myLightTypeArray.Size() < aNbLightsMax)
|
||||
{
|
||||
myLightTypeArray .Resize (0, aNbLightsMax - 1, false);
|
||||
myLightParamsArray.Resize (0, aNbLightsMax - 1, false);
|
||||
}
|
||||
for (Standard_Integer aLightIt = 0; aLightIt < aNbLightsMax; ++aLightIt)
|
||||
{
|
||||
myLightTypeArray.ChangeValue (aLightIt).Type = -1;
|
||||
}
|
||||
|
||||
if (myLightSourceState.LightSources() == NULL
|
||||
|| myLightSourceState.LightSources()->IsEmpty())
|
||||
const Standard_Integer aLightsDefNb = Min (myLightSourceState.LightSources()->Size(), OpenGLMaxLights);
|
||||
if (aLightsDefNb < 1)
|
||||
{
|
||||
theProgram->SetUniform (myContext,
|
||||
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
|
||||
0);
|
||||
theProgram->SetUniform (myContext,
|
||||
anAmbientLoc,
|
||||
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
|
||||
OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f));
|
||||
theProgram->SetUniform (myContext,
|
||||
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
|
||||
aNbLightsMax * OpenGl_ShaderLightType::NbOfVec2i(),
|
||||
myLightTypeArray.First().Packed());
|
||||
OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
|
||||
myLightTypeArray[0].Packed());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -685,20 +673,16 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
|
||||
anAmbient += aLight.Color;
|
||||
continue;
|
||||
}
|
||||
else if (aLightsNb >= aNbLightsMax)
|
||||
else if (aLightsNb >= OpenGLMaxLights)
|
||||
{
|
||||
if (aNbLightsMax != 0)
|
||||
{
|
||||
myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
|
||||
TCollection_AsciiString("Warning: light sources limit (") + aNbLightsMax + ") has been exceeded.");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
OpenGl_ShaderLightType& aLightType = myLightTypeArray.ChangeValue (aLightsNb);
|
||||
OpenGl_ShaderLightParameters& aLightParams = myLightParamsArray.ChangeValue (aLightsNb);
|
||||
OpenGl_ShaderLightType& aLightType = myLightTypeArray[aLightsNb];
|
||||
aLightType.Type = aLight.Type;
|
||||
aLightType.IsHeadlight = aLight.IsHeadlight;
|
||||
|
||||
OpenGl_ShaderLightParameters& aLightParams = myLightParamsArray[aLightsNb];
|
||||
aLightParams.Color = aLight.Color;
|
||||
if (aLight.Type == Graphic3d_TOLS_DIRECTIONAL)
|
||||
{
|
||||
@@ -731,18 +715,18 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
|
||||
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
|
||||
aLightsNb);
|
||||
theProgram->SetUniform (myContext,
|
||||
anAmbientLoc,
|
||||
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_AMBIENT),
|
||||
anAmbient);
|
||||
theProgram->SetUniform (myContext,
|
||||
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_TYPES),
|
||||
aNbLightsMax * OpenGl_ShaderLightType::NbOfVec2i(),
|
||||
myLightTypeArray.First().Packed());
|
||||
OpenGLMaxLights * OpenGl_ShaderLightType::NbOfVec2i(),
|
||||
myLightTypeArray[0].Packed());
|
||||
if (aLightsNb > 0)
|
||||
{
|
||||
theProgram->SetUniform (myContext,
|
||||
theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_PARAMS),
|
||||
aLightsNb * OpenGl_ShaderLightParameters::NbOfVec4(),
|
||||
myLightParamsArray.First().Packed());
|
||||
myLightParamsArray[0].Packed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,12 +907,8 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
|
||||
return;
|
||||
}
|
||||
|
||||
const Standard_Integer aNbMaxPlanes = myContext->MaxClipPlanes();
|
||||
if (myClipPlaneArrayFfp.Size() < aNbMaxPlanes)
|
||||
{
|
||||
myClipPlaneArrayFfp.Resize (0, aNbMaxPlanes - 1, false);
|
||||
}
|
||||
|
||||
const Standard_Integer aNbMaxPlanes = Min (myContext->MaxClipPlanes(), THE_MAX_CLIP_PLANES);
|
||||
OpenGl_Vec4d anEquations[THE_MAX_CLIP_PLANES];
|
||||
Standard_Integer aPlaneId = 0;
|
||||
Standard_Boolean toRestoreModelView = Standard_False;
|
||||
for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next())
|
||||
@@ -940,13 +920,14 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
|
||||
}
|
||||
else if (aPlaneId >= aNbMaxPlanes)
|
||||
{
|
||||
myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
|
||||
myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
|
||||
GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
|
||||
TCollection_ExtendedString("Warning: clipping planes limit (") + aNbMaxPlanes + ") has been exceeded.");
|
||||
break;
|
||||
}
|
||||
|
||||
const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
|
||||
OpenGl_Vec4d& aPlaneEq = myClipPlaneArrayFfp.ChangeValue (aPlaneId);
|
||||
OpenGl_Vec4d& aPlaneEq = anEquations[aPlaneId];
|
||||
aPlaneEq.x() = anEquation.x();
|
||||
aPlaneEq.y() = anEquation.y();
|
||||
aPlaneEq.z() = anEquation.z();
|
||||
@@ -995,8 +976,7 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
|
||||
return;
|
||||
}
|
||||
|
||||
const Standard_Integer aNbClipPlanesMax = theProgram->NbClipPlanesMax();
|
||||
const GLint aNbPlanes = Min (myContext->Clipping().NbClippingOrCappingOn(), aNbClipPlanesMax);
|
||||
const GLint aNbPlanes = Min (myContext->Clipping().NbClippingOrCappingOn(), THE_MAX_CLIP_PLANES);
|
||||
theProgram->SetUniform (myContext,
|
||||
theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT),
|
||||
aNbPlanes);
|
||||
@@ -1005,12 +985,8 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
|
||||
return;
|
||||
}
|
||||
|
||||
if (myClipPlaneArray.Size() < aNbClipPlanesMax)
|
||||
{
|
||||
myClipPlaneArray.Resize (0, aNbClipPlanesMax - 1, false);
|
||||
}
|
||||
|
||||
Standard_Integer aPlaneId = 0;
|
||||
OpenGl_Vec4 anEquations[THE_MAX_CLIP_PLANES];
|
||||
GLuint aPlaneId = 0;
|
||||
for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next())
|
||||
{
|
||||
const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
|
||||
@@ -1018,15 +994,16 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (aPlaneId >= aNbClipPlanesMax)
|
||||
else if (aPlaneId >= THE_MAX_CLIP_PLANES)
|
||||
{
|
||||
myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
|
||||
TCollection_AsciiString("Warning: clipping planes limit (") + aNbClipPlanesMax + ") has been exceeded.");
|
||||
myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
|
||||
GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
|
||||
"Warning: clipping planes limit (8) has been exceeded.");
|
||||
break;
|
||||
}
|
||||
|
||||
const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
|
||||
OpenGl_Vec4& aPlaneEq = myClipPlaneArray.ChangeValue (aPlaneId);
|
||||
OpenGl_Vec4& aPlaneEq = anEquations[aPlaneId];
|
||||
aPlaneEq.x() = float(anEquation.x());
|
||||
aPlaneEq.y() = float(anEquation.y());
|
||||
aPlaneEq.z() = float(anEquation.z());
|
||||
@@ -1040,7 +1017,7 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram)
|
||||
++aPlaneId;
|
||||
}
|
||||
|
||||
theProgram->SetUniform (myContext, aLocEquations, aNbClipPlanesMax, &myClipPlaneArray.First());
|
||||
theProgram->SetUniform (myContext, aLocEquations, THE_MAX_CLIP_PLANES, anEquations);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
@@ -1196,8 +1173,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFont()
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
aProgramSrc->SetNbLightsMax (0);
|
||||
aProgramSrc->SetNbClipPlanesMax (0);
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
TCollection_AsciiString aKey;
|
||||
@@ -1265,8 +1240,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFboBlit()
|
||||
aProgramSrc->SetHeader ("#version 150");
|
||||
}
|
||||
#endif
|
||||
aProgramSrc->SetNbLightsMax (0);
|
||||
aProgramSrc->SetNbClipPlanesMax (0);
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
TCollection_AsciiString aKey;
|
||||
@@ -1355,8 +1328,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramOitCompositing (const St
|
||||
#endif
|
||||
}
|
||||
|
||||
aProgramSrc->SetNbLightsMax (0);
|
||||
aProgramSrc->SetNbClipPlanesMax (0);
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
TCollection_AsciiString aKey;
|
||||
@@ -1492,8 +1463,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
aSrcFragExtraOut += EOL"THE_SHADER_IN vec4 VertColor;";
|
||||
aSrcFragGetColor = EOL"vec4 getColor(void) { return VertColor; }";
|
||||
}
|
||||
|
||||
int aNbClipPlanes = 0;
|
||||
if ((theBits & OpenGl_PO_ClipPlanesN) != 0)
|
||||
{
|
||||
aSrcVertExtraOut +=
|
||||
@@ -1508,17 +1477,14 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
|
||||
if ((theBits & OpenGl_PO_ClipPlanes1) != 0)
|
||||
{
|
||||
aNbClipPlanes = 1;
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_1;
|
||||
}
|
||||
else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
|
||||
{
|
||||
aNbClipPlanes = 2;
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
aNbClipPlanes = Graphic3d_ShaderProgram::THE_MAX_CLIP_PLANES_DEFAULT;
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
|
||||
}
|
||||
}
|
||||
@@ -1609,8 +1575,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramFlat (Handle(OpenGl_Shad
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
aProgramSrc->SetNbLightsMax (0);
|
||||
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
|
||||
@@ -1661,14 +1625,12 @@ TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TColl
|
||||
// function : stdComputeLighting
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights,
|
||||
Standard_Boolean theHasVertColor)
|
||||
TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (const Standard_Boolean theHasVertColor)
|
||||
{
|
||||
Standard_Integer aLightsMap[Graphic3d_TOLS_SPOT + 1] = { 0, 0, 0, 0 };
|
||||
TCollection_AsciiString aLightsFunc, aLightsLoop;
|
||||
const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
|
||||
if (aLights != NULL)
|
||||
theNbLights = 0;
|
||||
{
|
||||
Standard_Integer anIndex = 0;
|
||||
for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next(), ++anIndex)
|
||||
@@ -1690,7 +1652,6 @@ TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integ
|
||||
}
|
||||
aLightsMap[aLightIter.Value().Type] += 1;
|
||||
}
|
||||
theNbLights = anIndex;
|
||||
const Standard_Integer aNbLoopLights = aLightsMap[Graphic3d_TOLS_DIRECTIONAL]
|
||||
+ aLightsMap[Graphic3d_TOLS_POSITIONAL]
|
||||
+ aLightsMap[Graphic3d_TOLS_SPOT];
|
||||
@@ -1801,7 +1762,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
aSrcVertColor = EOL"vec4 getVertColor(void) { return occVertColor; }";
|
||||
}
|
||||
|
||||
int aNbClipPlanes = 0;
|
||||
if ((theBits & OpenGl_PO_ClipPlanesN) != 0)
|
||||
{
|
||||
aSrcVertExtraOut +=
|
||||
@@ -1816,17 +1776,14 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
|
||||
if ((theBits & OpenGl_PO_ClipPlanes1) != 0)
|
||||
{
|
||||
aNbClipPlanes = 1;
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_1;
|
||||
}
|
||||
else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
|
||||
{
|
||||
aNbClipPlanes = 2;
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
aNbClipPlanes = Graphic3d_ShaderProgram::THE_MAX_CLIP_PLANES_DEFAULT;
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
|
||||
}
|
||||
}
|
||||
@@ -1835,8 +1792,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
aSrcFragWriteOit += THE_FRAG_write_oit_buffers;
|
||||
}
|
||||
|
||||
Standard_Integer aNbLights = 0;
|
||||
const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, (theBits & OpenGl_PO_VertColor) != 0);
|
||||
const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
|
||||
aSrcVert = TCollection_AsciiString()
|
||||
+ THE_FUNC_transformNormal
|
||||
+ EOL
|
||||
@@ -1882,8 +1838,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramGouraud (Handle(OpenGl_S
|
||||
aProgramSrc->SetHeader ("#version 300 es");
|
||||
}
|
||||
#endif
|
||||
aProgramSrc->SetNbLightsMax (aNbLights);
|
||||
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
TCollection_AsciiString aKey;
|
||||
@@ -1960,22 +1914,18 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
EOL"vec4 getVertColor(void) { return VertColor; }";
|
||||
}
|
||||
|
||||
int aNbClipPlanes = 0;
|
||||
if ((theBits & OpenGl_PO_ClipPlanesN) != 0)
|
||||
{
|
||||
if ((theBits & OpenGl_PO_ClipPlanes1) != 0)
|
||||
{
|
||||
aNbClipPlanes = 1;
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_1;
|
||||
}
|
||||
else if ((theBits & OpenGl_PO_ClipPlanes2) != 0)
|
||||
{
|
||||
aNbClipPlanes = 2;
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
aNbClipPlanes = Graphic3d_ShaderProgram::THE_MAX_CLIP_PLANES_DEFAULT;
|
||||
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES_N;
|
||||
}
|
||||
}
|
||||
@@ -2005,8 +1955,7 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
+ EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
|
||||
EOL"}";
|
||||
|
||||
Standard_Integer aNbLights = 0;
|
||||
const TCollection_AsciiString aLights = stdComputeLighting (aNbLights, (theBits & OpenGl_PO_VertColor) != 0);
|
||||
const TCollection_AsciiString aLights = stdComputeLighting ((theBits & OpenGl_PO_VertColor) != 0);
|
||||
aSrcFrag = TCollection_AsciiString()
|
||||
+ EOL"THE_SHADER_IN vec4 PositionWorld;"
|
||||
EOL"THE_SHADER_IN vec4 Position;"
|
||||
@@ -2054,8 +2003,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_Sha
|
||||
}
|
||||
}
|
||||
#endif
|
||||
aProgramSrc->SetNbLightsMax (aNbLights);
|
||||
aProgramSrc->SetNbClipPlanesMax (aNbClipPlanes);
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
TCollection_AsciiString aKey;
|
||||
@@ -2278,8 +2225,6 @@ Standard_Boolean OpenGl_ShaderManager::prepareStdProgramStereo (Handle(OpenGl_Sh
|
||||
}
|
||||
#endif
|
||||
|
||||
aProgramSrc->SetNbLightsMax (0);
|
||||
aProgramSrc->SetNbClipPlanesMax (0);
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
|
||||
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
|
||||
TCollection_AsciiString aKey;
|
||||
|
@@ -444,10 +444,8 @@ protected:
|
||||
const Standard_Boolean theIsFlatNormal = false);
|
||||
|
||||
//! Define computeLighting GLSL function depending on current lights configuration
|
||||
//! @param theNbLights [out] number of defined light sources
|
||||
//! @param theHasVertColor [in] flag to use getVertColor() instead of Ambient and Diffuse components of active material
|
||||
Standard_EXPORT TCollection_AsciiString stdComputeLighting (Standard_Integer& theNbLights,
|
||||
Standard_Boolean theHasVertColor);
|
||||
//! @param theHasVertColor flag to use getVertColor() instead of Ambient and Diffuse components of active material
|
||||
Standard_EXPORT TCollection_AsciiString stdComputeLighting (const Standard_Boolean theHasVertColor);
|
||||
|
||||
//! Bind specified program to current context and apply state.
|
||||
Standard_EXPORT Standard_Boolean bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram);
|
||||
@@ -524,10 +522,8 @@ protected:
|
||||
gp_XYZ myLocalOrigin; //!< local camera transformation
|
||||
Standard_Boolean myHasLocalOrigin; //!< flag indicating that local camera transformation has been set
|
||||
|
||||
mutable NCollection_Array1<OpenGl_ShaderLightType> myLightTypeArray;
|
||||
mutable NCollection_Array1<OpenGl_ShaderLightParameters> myLightParamsArray;
|
||||
mutable NCollection_Array1<OpenGl_Vec4> myClipPlaneArray;
|
||||
mutable NCollection_Array1<OpenGl_Vec4d> myClipPlaneArrayFfp;
|
||||
mutable OpenGl_ShaderLightType myLightTypeArray [OpenGLMaxLights];
|
||||
mutable OpenGl_ShaderLightParameters myLightParamsArray[OpenGLMaxLights];
|
||||
|
||||
private:
|
||||
|
||||
|
@@ -149,8 +149,6 @@ OpenGl_ShaderProgram::OpenGl_ShaderProgram (const Handle(Graphic3d_ShaderProgram
|
||||
myProgramID (NO_PROGRAM),
|
||||
myProxy (theProxy),
|
||||
myShareCount(1),
|
||||
myNbLightsMax (0),
|
||||
myNbClipPlanesMax (0),
|
||||
myHasTessShader (false)
|
||||
{
|
||||
memset (myCurrentState, 0, sizeof (myCurrentState));
|
||||
@@ -329,24 +327,11 @@ Standard_Boolean OpenGl_ShaderProgram::Initialize (const Handle(OpenGl_Context)&
|
||||
case Graphic3d_TOS_FRAGMENT: { aHeaderType = "#define FRAGMENT_SHADER\n"; break; }
|
||||
}
|
||||
|
||||
TCollection_AsciiString aHeaderConstants;
|
||||
myNbLightsMax = !myProxy.IsNull() ? myProxy->NbLightsMax() : 0;
|
||||
myNbClipPlanesMax = !myProxy.IsNull() ? myProxy->NbClipPlanesMax() : 0;
|
||||
if (myNbLightsMax > 0)
|
||||
{
|
||||
aHeaderConstants += TCollection_AsciiString("#define THE_MAX_LIGHTS ") + myNbLightsMax + "\n";
|
||||
}
|
||||
if (myNbClipPlanesMax > 0)
|
||||
{
|
||||
aHeaderConstants += TCollection_AsciiString("#define THE_MAX_CLIP_PLANES ") + myNbClipPlanesMax + "\n";
|
||||
}
|
||||
|
||||
const TCollection_AsciiString aSource = aHeaderVer // #version - header defining GLSL version, should be first
|
||||
+ (!aHeaderVer.IsEmpty() ? "\n" : "")
|
||||
+ anExtensions // #extension - list of enabled extensions, should be second
|
||||
+ aPrecisionHeader // precision - default precision qualifiers, should be before any code
|
||||
+ aHeaderType // auxiliary macros defining a shader stage (type)
|
||||
+ aHeaderConstants
|
||||
+ Shaders_Declarations_glsl // common declarations (global constants and Vertex Shader inputs)
|
||||
+ Shaders_DeclarationsImpl_glsl
|
||||
+ anIter.Value()->Source(); // the source code itself (defining main() function)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user