1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-01 17:36:21 +03:00

0032340: OCCT Documentation - highlight C++ code snippets

Added {.cpp} highlighting markers to the C++ code blocks in documentation;
Excessive tildes "~~~~~~~" in code block borders are reduced to required minimum of "~~~~" (4);
Removed obsolete space bars after code block borders;
TCL code blocks are now highlighted with {.php} markers;
Removed excessive {.cpp} highlighting markers appended to non-code blocks such as lists, reports and file content or structure examples;
Minor fixes for tests.md and draw_test_harness.md (whitespace removal and structural fix for "Where:" in code examples);
Minimum HDD space for OCCT updated in introduction.md.
This commit is contained in:
btokarev 2021-05-18 13:09:50 +03:00 committed by bugmaster
parent 4d67a36952
commit 77d94fd174
25 changed files with 4576 additions and 4571 deletions

View File

@ -243,9 +243,9 @@ The environment is defined in the file *custom.sh* (on Linux and OS X) or *custo
* *ShortCut* - short-cut header files will be created, redirecting to same-named header located in *src*;
* "HardLink* - hard links to headers located in *src* will be created.
* For optional third-party libraries, set corresponding environment variable <i>HAVE_<LIBRARY_NAME></i> to either *false*, e.g.:
~~~~~
~~~~
export HAVE_FREEIMAGE=false
~~~~~
~~~~
Alternatively, or when *custom.sh* or *custom.bat* does not exist, you can launch **genconf** tool to configure environment interactively:
@ -257,10 +257,10 @@ Click "Save" to store the specified configuration in *custom.sh* or *custom.bat*
Launch **genproj** tool with option *cbp* to update content of *inc* folder and generate project files after changes in OCCT code affecting layout or composition of source files:
~~~~~
~~~~
$ cd /dev/OCCT/opencascade-7.0.0
$ ./genproj cbp
~~~~~
~~~~
The generated Code::Blocks project are placed into subfolder *adm/&lt;OS&gt;/cbp*.
@ -273,9 +273,9 @@ To start **Code::Blocks**, launch script *codeblocks.sh*.
To build all toolkits, click **Build->Build workspace** in the menu bar.
To start *DRAWEXE*, which has been built with **Code::Blocks** on Mac OS X, run the script
~~~~~
~~~~
./draw.sh cbp [d]
~~~~~
~~~~
Option *d* is used if OCCT has been built in **Debug** mode.
@subsection build_occt_genproj Building with Genproj tool
@ -344,9 +344,9 @@ Launch **genproj** to update content of *inc* folder and generate project files
@note To use **genproj** and **genconf** tools you need to have Tcl installed and accessible by PATH.
If Tcl is not found, the tool may prompt you to enter the path to directory where Tcl can be found.
~~~~~
~~~~
$ genproj.bat
~~~~~
~~~~
Note that if *custom.bat* is not present, **genproj** will start **genconf** to configure environment.
@ -470,9 +470,9 @@ The environment is defined in the file *custom.sh* which can be edited directly:
* *ShortCut* - short-cut header files will be created, redirecting to same-named header located in *src*;
* "HardLink* - hard links to headers located in *src* will be created.
* For optional third-party libraries, set corresponding environment variable <i>HAVE_<LIBRARY_NAME></i> to either *false*, e.g.:
~~~~~
~~~~
export HAVE_FREEIMAGE=false
~~~~~
~~~~
Alternatively, or when *custom.sh* does not exist, you can launch *genconf.sh* to configure environment interactively:
@ -488,10 +488,10 @@ Launch **genproj** tool to update content of *inc* folder and generate project f
For instance, in Terminal application:
~~~~~
~~~~
$ cd /dev/OCCT/opencascade-7.0.0
$ ./genproj
~~~~~
~~~~
<h2>Building</h2>
@ -513,14 +513,14 @@ To start *DRAWEXE*, which has been built with Xcode on Mac OS X, perform the fol
1.Open Terminal application
2.Enter <i>\<OCCT_ROOT_DIR\></i>:
~~~~~
~~~~
cd \<OCCT_ROOT_DIR\>
~~~~~
~~~~
3.Run the script
~~~~~
~~~~
./draw_cbp.sh xcd [d]
~~~~~
~~~~
Option *d* is used if OCCT has been built in **Debug** mode.
@ -543,9 +543,9 @@ directly:
* *ShortCut* - short-cut header files will be created, redirecting to same-named header located in *src*;
* "HardLink* - hard links to headers located in *src* will be created.
* For optional third-party libraries, set corresponding environment variable <i>HAVE_<LIBRARY_NAME></i> to either *false*, e.g.:
~~~~~
~~~~
export HAVE_FREEIMAGE=false
~~~~~
~~~~
Alternatively, or when *custom.sh* or *custom.bat* does not exist, you can launch **genconf** tool to configure
environment interactively:
@ -559,10 +559,10 @@ Click "Save" to store the specified configuration in *custom.sh* or *custom.bat*
Launch **genproj** tool with option *cbp* to update content of *inc* folder and generate project files after changes in
OCCT code affecting layout or composition of source files:
~~~~~
~~~~
$ cd /dev/OCCT/opencascade-7.0.0
$ ./genproj cbp
~~~~~
~~~~
The generated Code::Blocks project are placed into subfolder *adm/&lt;OS&gt;/cbp*.
@ -575,7 +575,7 @@ To start **Code::Blocks**, launch script *codeblocks.sh*.
To build all toolkits, click **Build->Build workspace** in the menu bar.
To start *DRAWEXE*, which has been built with **Code::Blocks** on Mac OS X, run the script
~~~~~
~~~~
./draw_cbp.sh cbp [d]
~~~~~
~~~~
Option *d* is used if OCCT has been built in **Debug** mode.

View File

@ -48,11 +48,11 @@ For example, method *GetCoord* returns a triple of real values and is defined fo
Camel Case style is preferred for names.
For example:
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer awidthofbox; // this is bad
Standard_Integer width_of_box; // this is bad
Standard_Integer aWidthOfBox; // this is OK
~~~~~
~~~~
@subsection occt_coding_rules_2_2 Names of development units
@ -80,9 +80,9 @@ Toolkit names are prefixed by *TK*, followed by a meaningful part of the name ex
Names of public classes and other types (structures, enums, typedefs) should match the common pattern: name of the package followed by underscore and suffix (the own name of the type):
~~~~~
~~~~{.cpp}
<package-name>_<class-name>
~~~~~
~~~~
Static methods related to the whole package are defined in the class with the same name as package (without suffix).
@ -95,9 +95,9 @@ This rule also applies to complex types constructed by instantiation of template
Such types should be given own names using *typedef* statement, located in same-named header file.
For example, see definition in the file *TColStd_IndexedDataMapOfStringString.hxx*:
~~~~~
~~~~{.cpp}
typedef NCollection_IndexedDataMap<TCollection_AsciiString,TCollection_AsciiString,TCollection_AsciiString> TColStd_IndexedDataMapOfStringString;
~~~~~
~~~~
### Names of functions
@ -109,7 +109,7 @@ The term **function** here is defined as:
It is preferred to start names of public methods from an upper case character and to start names of protected and private methods from a lower case character.
~~~~~{.cpp}
~~~~{.cpp}
class MyPackage_MyClass
{
@ -123,7 +123,7 @@ private:
void setIntegerValue (const Standard_Integer theValue);
};
~~~~~
~~~~
@subsection occt_coding_rules_2_3 Names of variables
@ -137,13 +137,13 @@ The name of a variable should not start with an underscore.
See the following examples:
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer Elapsed_Time = 0; // this is bad - possible class name
Standard_Integer gp = 0; // this is bad - existing package name
Standard_Integer aGp = 0; // this is OK
Standard_Integer _KERNEL = 0; // this is bad
Standard_Integer THE_KERNEL = 0; // this is OK
~~~~~
~~~~
### Names of function parameters
@ -151,11 +151,11 @@ The name of a function (procedure, class method) parameter should start with pre
See the following examples:
~~~~~{.cpp}
~~~~{.cpp}
void Package_MyClass::MyFunction (const gp_Pnt& p); // this is bad
void Package_MyClass::MyFunction (const gp_Pnt& theP); // this is OK
void Package_MyClass::MyFunction (const gp_Pnt& thePoint); // this is preferred
~~~~~
~~~~
### Names of class member variables
@ -163,11 +163,11 @@ The name of a class member variable should start with prefix *my* followed by th
See the following examples:
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer counter; // This is bad
Standard_Integer myC; // This is OK
Standard_Integer myCounter; // This is preferred
~~~~~
~~~~
### Names of global variables
@ -176,18 +176,18 @@ However, as soon as a global variable is necessary, its name should be prefixed
See the following examples:
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer MyPackage_myGlobalVariable = 0;
Standard_Integer MyPackage_MyClass_myGlobalVariable = 0;
~~~~~
~~~~
Static constants within the file should be written in upper-case and begin with prefix *THE_*:
~~~~~{.cpp}
~~~~{.cpp}
namespace
{
static const Standard_Real THE_CONSTANT_COEF = 3.14;
};
~~~~~
~~~~
### Names of local variables
@ -197,12 +197,12 @@ It is preferred to prefix local variable names with *a* and *an* (or *is*, *to*
See the following example:
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer theI; // this is bad
Standard_Integer i; // this is bad
Standard_Integer index; // this is bad
Standard_Integer anIndex; // this is OK
~~~~~
~~~~
### Avoid dummy names
Avoid dummy names, such as <i>i, j, k</i>. Such names are meaningless and easy to mix up.
@ -211,7 +211,7 @@ The code becomes more and more complicated when such dummy names are used there
See the following examples for preferred style:
~~~~~{.cpp}
~~~~{.cpp}
void Average (const Standard_Real** theArray,
Standard_Integer theRowsNb,
Standard_Integer theRowLen,
@ -227,7 +227,7 @@ void Average (const Standard_Real** theArray,
theResult /= Standard_Real(aRowsNb * aRowLen);
}
}
~~~~~
~~~~
@section occt_coding_rules_3 Formatting rules
@ -262,7 +262,7 @@ Punctuation rules follow the rules of the English language.
* For better readability it is also recommended to surround conventional operators by a space character.
Examples:
~~~~~{.cpp}
~~~~{.cpp}
while (true) // NOT: while( true ) ...
{
DoSomething (theA, theB, theC, theD); // NOT: DoSomething(theA,theB,theC,theD);
@ -271,7 +271,7 @@ for (anIter = 0; anIter < 10; ++anIter) // NOT: for (anIter=0;anIter<10;++anIter
{
theA = (theB + theC) * theD; // NOT: theA=(theB+theC)*theD
}
~~~~~
~~~~
### Declaration of pointers and references
@ -281,7 +281,7 @@ Since declaration of several variables with mixed pointer types contrudicts this
Examples:
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer *theVariable; // not recommended
Standard_Integer * theVariable; // not recommended
Standard_Integer* theVariable; // this is OK
@ -295,7 +295,7 @@ Standard_Integer ** theVariable; // not recommended
Standard_Integer** theVariable; // this is OK
Standard_Integer *theA, theB, **theC; // not recommended (declare each variable independently)
~~~~~
~~~~
### Separate logical blocks
@ -303,7 +303,7 @@ Separate logical blocks of code with one blank line and comments.
See the following example:
~~~~~{.cpp}
~~~~{.cpp}
// check arguments
Standard_Integer anArgsNb = argCount();
if (anArgsNb < 3 || isSmthInvalid)
@ -318,7 +318,7 @@ if (anArgsNb < 3 || isSmthInvalid)
// do our job
...
...
~~~~~
~~~~
Notice that multiple blank lines should be avoided.
@ -329,7 +329,7 @@ Each descriptive block should contain at least a function name and purpose descr
See the following example:
~~~~~{.cpp}
~~~~{.cpp}
// =======================================================================
// function : TellMeSmthGood
// purpose : Gives me good news
@ -347,19 +347,19 @@ void TellMeSmthBad()
{
...
}
~~~~~
~~~~
### Block layout [MANDATORY]
Figure brackets <i>{ }</i> and each operator <i>(for, if, else, try, catch)</i> should be written on a dedicated line.
In general, the layout should be as follows:
~~~~~{.cpp}
~~~~{.cpp}
while (expression)
{
...
}
~~~~~
~~~~
Entering a block increases and leaving a block decreases the indentation by one tabulation.
@ -367,7 +367,7 @@ Entering a block increases and leaving a block decreases the indentation by one
Single-line conditional operators <i>(if, while, for,</i> etc.) can be written without brackets on the following line.
~~~~~{.cpp}
~~~~{.cpp}
if (!myIsInit) return Standard_False; // bad
if (thePtr == NULL) // OK
@ -377,7 +377,7 @@ if (!theAlgo.IsNull()) // preferred
{
DoSomething();
}
~~~~~
~~~~
Having all code in the same line is less convenient for debugging.
@ -386,7 +386,7 @@ Having all code in the same line is less convenient for debugging.
In comparisons, put the variable (in the current context) on the left side and constant on the right side of expression.
That is, the so called "Yoda style" is to be avoided.
~~~~~{.cpp}
~~~~{.cpp}
if (NULL != thePointer) // Yoda style, not recommended
if (thePointer != NULL) // OK
@ -398,13 +398,13 @@ if (anIter <= theNbValues) // OK
if (THE_LIMIT == theValue) // bad style (global constant vs. variable)
if (theValue == THE_LIMIT) // OK
~~~~~
~~~~
### Alignment
Use alignment wherever it enhances the readability. See the following example:
~~~~~{.cpp}
~~~~{.cpp}
MyPackage_MyClass anObject;
Standard_Real aMinimum = 0.0;
Standard_Integer aVal = theVal;
@ -415,7 +415,7 @@ switch (aVal)
case 3:
default: computeSomethingElseYet(); break;
}
~~~~~
~~~~
### Indentation of comments
@ -425,7 +425,7 @@ The text of the comment should be separated from the slash character by a single
See the following example:
~~~~~{.cpp}
~~~~{.cpp}
while (expression) //bad comment
{
// this is a long multi-line comment
@ -433,7 +433,7 @@ while (expression) //bad comment
DoSomething(); // maybe, enough
DoSomethingMore(); // again
}
~~~~~
~~~~
### Early return statement
@ -441,7 +441,7 @@ Use an early return condition rather than collect indentations.
Write like this:
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer ComputeSumm (const Standard_Integer* theArray,
const Standard_Size theSize)
{
@ -454,11 +454,11 @@ Standard_Integer ComputeSumm (const Standard_Integer* theArray,
... computing summ ...
return aSumm;
}
~~~~~
~~~~
Rather than:
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer ComputeSumm (const Standard_Integer* theArray,
const Standard_Size theSize)
{
@ -469,7 +469,7 @@ Standard_Integer ComputeSumm (const Standard_Integer* theArray,
}
return aSumm;
}
~~~~~
~~~~
This helps to improve readability and reduce the unnecessary indentation depth.
@ -490,7 +490,7 @@ An exception to the rule is ordering system headers generating a macros declarat
The source or header file should include only minimal set of headers necessary for compilation, without duplicates (considering nested includes).
~~~~~{.cpp}
~~~~{.cpp}
// the header file of implemented class
#include <PackageName_ClassName.hxx>
@ -506,7 +506,7 @@ The source or header file should include only minimal set of headers necessary f
// system headers
#include <iostream>
#include <windows.h>
~~~~~
~~~~
@section occt_coding_rules_4 Documentation rules
@ -623,7 +623,7 @@ A class with virtual function(s) ought to have a virtual destructor.
Declaration of overriding method should contains specifiers "virtual" and "override"
(using Standard_OVERRIDE alias for compatibility with old compilers).
~~~~~{.cpp}
~~~~{.cpp}
class MyPackage_BaseClass
{
@ -641,7 +641,7 @@ public:
Standard_EXPORT virtual Standard_Boolean Perform() Standard_OVERRIDE;
};
~~~~~
~~~~
This makes class definition more clear (virtual methods become highlighted).
@ -667,20 +667,20 @@ Avoid *goto* statement unless it is really needed.
Declare a cycle variable in the header of the *for()* statement if not used out of cycle.
~~~~~{.cpp}
~~~~{.cpp}
Standard_Real aMinDist = Precision::Infinite();
for (NCollection_Sequence<gp_Pnt>::Iterator aPntIter (theSequence);
aPntIter.More(); aPntIter.Next())
{
aMinDist = Min (aMinDist, theOrigin.Distance (aPntIter.Value()));
}
~~~~~
~~~~
### Condition statements within zero
Avoid usage of C-style comparison for non-boolean variables:
~~~~~{.cpp}
~~~~{.cpp}
void Function (Standard_Integer theValue,
Standard_Real* thePointer)
{
@ -699,7 +699,7 @@ void Function (Standard_Integer theValue,
DoSome2();
}
}
~~~~~
~~~~
@section occt_coding_rules_7 Portability issues
@ -791,11 +791,11 @@ In C++ use *new* and *delete* operators instead of *malloc()* and *free()*. Try
Use the same form of new and delete.
~~~~~{.cpp}
~~~~{.cpp}
aPtr1 = new TypeA[n]; ... ; delete[] aPtr1;
aPtr2 = new TypeB(); ... ; delete aPtr2;
aPtr3 = Standard::Allocate (4096); ... ; Standard::Free (aPtr3);
~~~~~
~~~~
### Methods managing dynamical allocation [MANDATORY]
@ -805,10 +805,10 @@ Define a destructor, a copy constructor and an assignment operator for classes w
Every variable should be initialized.
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer aTmpVar1; // bad
Standard_Integer aTmpVar2 = 0; // OK
~~~~~
~~~~
Uninitialized variables might be kept only within performance-sensitive code blocks and only when their initialization is guaranteed by subsequent code.
@ -824,12 +824,12 @@ In *operator=()* assign to all data members and check for assignment to self.
Don't check floats for equality or non-equality; check for GT, GE, LT or LE.
~~~~~{.cpp}
~~~~{.cpp}
if (Abs (theFloat1 - theFloat2) < theTolerance)
{
DoSome();
}
~~~~~
~~~~
Package *Precision* provides standard values for SI units and widely adopted by existing modeling algorithms:
@ -872,7 +872,7 @@ Generally, try to reduce misaligned accesses since they impact the performance (
List class data members in the constructor's initialization list in the order they are declared.
~~~~~{.cpp}
~~~~{.cpp}
class MyPackage_MyClass
{
@ -892,19 +892,19 @@ private:
Standard_Integer myPropertyB;
};
~~~~~
~~~~
### Initialization over assignment
Prefer initialization over assignment in class constructors.
~~~~~{.cpp}
~~~~{.cpp}
MyPackage_MyClass()
: myPropertyA (1) // preferred
{
myPropertyB = 2; // not recommended
}
~~~~~
~~~~
### Optimize caching
@ -912,23 +912,23 @@ When programming procedures with extensive memory access, try to optimize them i
On x86 this code
~~~~~{.cpp}
~~~~{.cpp}
Standard_Real anArray[4096][2];
for (Standard_Integer anIter = 0; anIter < 4096; ++anIter)
{
anArray[anIter][0] = anArray[anIter][1];
}
~~~~~
~~~~
is more efficient then
~~~~~{.cpp}
~~~~{.cpp}
Standard_Real anArray[2][4096];
for (Standard_Integer anIter = 0; anIter < 4096; ++anIter)
{
anArray[0][anIter] = anArray[1][anIter];
}
~~~~~
~~~~
since linear access does not invalidate cache too often.
@ -952,7 +952,7 @@ Command arguments should be validated before usage. The user should see a human-
Command should warn the user about unknown arguments, including cases when extra parameters have been pushed for the command with a fixed number of arguments.
~~~~~{.cpp}
~~~~{.cpp}
if (theArgsNb != 3)
{
std::cout << "Syntax error - wrong number of arguments!\n";
@ -971,7 +971,7 @@ Command should warn the user about unknown arguments, including cases when extra
}
DBRep::Set (aResName, aFaceShape);
return 0;
~~~~~
~~~~
### Message printing
@ -984,9 +984,9 @@ Information printed into Draw Interpreter should be well-structured to allow usa
Any command with a long list of obligatory parameters should be considered as ill-formed by design.
Optional parameters should start with flag name (with '-' prefix) and followed by its values:
~~~~~{.tcl}
~~~~{.php}
myCommand -flag1 value1 value2 -flag2 value3
~~~~~
~~~~
### Arguments parser
@ -996,7 +996,7 @@ myCommand -flag1 value1 value2 -flag2 value3
Functions *Draw::Atof()* and *Draw::Atoi()* support expressions and read values in C-locale.
~~~~~{.cpp}
~~~~{.cpp}
Standard_Real aPosition[3] = {0.0, 0.0, 0.0};
for (Standard_Integer anArgIter = 1; anArgIter < theArgsNb; ++anArgIter)
{
@ -1020,7 +1020,7 @@ Functions *Draw::Atof()* and *Draw::Atoi()* support expressions and read values
return 1;
}
}
~~~~~
~~~~
@section occt_coding_rules_11 Examples
@ -1051,7 +1051,7 @@ private: //! \@name private fields
@endverbatim
~~~~~
~~~~{.cpp}
#include <Package_Class.hxx>
// ==========================================================
// function : Square
@ -1071,11 +1071,11 @@ void Package_Class::increment()
{
++myCounter;
}
~~~~~
~~~~
### TCL script for Draw Harness
~~~~~{.tcl}
~~~~{.tcl}
# show fragments (solids) in shading with different colors
proc DisplayColored {theShape} {
set aSolids [uplevel #0 explode $theShape so]
@ -1106,10 +1106,10 @@ vzbufftrihedron
DisplayColored c
vfit
vdump $imagedir/${casename}.png 512 512
~~~~~
~~~~
### GLSL program:
~~~~~{.fs}
~~~~{.cpp}
vec3 Ambient; //!< Ambient contribution of light sources
vec3 Diffuse; //!< Diffuse contribution of light sources
vec3 Specular; //!< Specular contribution of light sources
@ -1149,4 +1149,4 @@ void main()
normalize (View),
Position);
}
~~~~~
~~~~

View File

@ -152,11 +152,11 @@ The official repository contains:
Make sure to configure Git so that the user name is equal to your username
on the OCCT development portal, and set SafeCrLf option to true:
~~~~~
~~~~
> git config --global user.name "Your User Name"
> git config --global user.email your@mail.address
> git config --global your@mail.address
~~~~~
~~~~
@section occt_gitguide_3 Getting access to the repository
@ -213,9 +213,9 @@ The official repository contains:
On Windows, you might need to start **Git Bash** command prompt window.
Use the following command to generate SSH keys:
~~~~~
~~~~
> ssh-keygen -t rsa -C "your@mail.address"
~~~~~
~~~~
The last argument is an optional comment, which can be included with the public key and used to distinguish between different keys (if you have many). The common practice is to put here your mail address or workstation name.
@ -290,9 +290,9 @@ Click **Save** to input the key to the system.
* From command line by command:
~~~~~
~~~~
> git clone gitolite@git.dev.opencascade.org:occt <path>
~~~~~
~~~~
where <i>\<path\></i> is the path to the new folder which will be created for the repository.
@ -314,9 +314,9 @@ Click **Save** to input the key to the system.
In the console:
~~~~~
~~~~
> git checkout -b CR12345 origin/master
~~~~~
~~~~
In TortoiseGit:
* Go to the local copy of the repository.
@ -332,9 +332,9 @@ In TortoiseGit:
If you need to switch to another branch, use Git command checkout for that.
In the console:
~~~~~
~~~~
> git checkout CR12345
~~~~~
~~~~
In TortoiseGit: right-click in the explorer window and select in the context menu **TortoiseGit** -> **Switch/Checkout**.
@ -351,11 +351,11 @@ In TortoiseGit:
* In the console:
~~~~~
~~~~
> git diff
> git commit -a -m "Write meaningful commit message here"
~~~~~
~~~~
Option -a tells the command to automatically include (stage) files
that have been modified or deleted, but it will omit the new files that might have been added by you.
@ -363,12 +363,12 @@ In TortoiseGit:
To find new unstaged files and them to commit, use commands:
~~~~~
~~~~
> git status -s
?? file1.hxx
?? file2.cxx
> git add file1.hxx file2.cxx
~~~~~
~~~~
* In TortoiseGit: right-click in the explorer window and select in the context menu <b>Git Commit -> CR…</b>:
@ -384,9 +384,9 @@ In TortoiseGit:
* In the console:
~~~~~
~~~~
> git push "origin" CR12345:CR12345
~~~~~
~~~~
* In TortoiseGit: right-click in the explorer window and select in the context menu, TortoiseGit -> **Push**
@ -410,9 +410,9 @@ Note that Git forbids pushing a branch if the corresponding remote branch alread
Use Git command *fetch* with option *prune* to get the update of all branches from the remote repository and to clean your local repository from the remote branches that have been deleted.
* In the console:
~~~~~
~~~~
> git fetch --prune
~~~~~
~~~~
* In TortoiseGit: right-click in the explorer window and select in the context menu **TortoiseGit** -> **Fetch**. Check in **Prune** check-box.
@ -423,9 +423,9 @@ Note that Git forbids pushing a branch if the corresponding remote branch alread
This operation is required in particular to update your local master branch when the remote master changes.
* In console:
~~~~~
~~~~
> git pull
~~~~~
~~~~
* In TortoiseGit: right-click in the explorer window and select in the context menu **TortoiseGit** -> **Pull**.
@ -436,9 +436,9 @@ Note that the local branches of your repository are the primary place, where you
Remove the local branches that you do not need any more. Note that you cannot delete the current branch. It means that you need to switch to another one (e.g. master) if the branch you are going to delete is the current one.
* In the console:
~~~~~
~~~~
> git branch -d CR12345
~~~~~
~~~~
* In TortoiseGit: right-click in the explorer window and select in the context menu **TortoiseGit** -> **Git Show Log**.

File diff suppressed because it is too large Load Diff

View File

@ -49,34 +49,34 @@ Open CASCADE Test Harness or @ref occt_user_guides__test_harness "DRAW" provides
In some cases the objects to be inspected are available in DRAW as results of DRAW commands. In other cases, however, it is necessary to inspect intermediate objects created by the debugged algorithm. To support this, DRAW provides a set of commands allowing the developer to store intermediate objects directly from the debugger stopped at some point during the program execution (usually at a breakpoint).
~~~~~
~~~~{.php}
const char* Draw_Eval (const char *theCommandStr)
~~~~~
~~~~
Evaluates a DRAW command or script.
A command is passed as a string parameter.
~~~~~
~~~~{.php}
const char* DBRep_Set (const char* theNameStr, void* theShapePtr)
~~~~~
~~~~
Sets the specified shape as a value of DRAW interpreter variable with the given name.
- *theNameStr* -- the DRAW interpreter variable name to set.
- *theShapePtr* -- a pointer to *TopoDS_Shape* variable.
~~~~~
~~~~{.php}
const char* DBRep_SetComp (const char* theNameStr, void* theListPtr)
~~~~~
~~~~
Makes a compound from the specified list of shapes and sets it as a value of DRAW interpreter variable with the given name.
- *theNameStr* -- the DRAW interpreter variable name to set.
- *theListPtr* -- a pointer to *TopTools_ListOfShape* variable.
~~~~~
~~~~{.php}
const char* DrawTrSurf_Set (const char* theNameStr, void* theHandlePtr)
const char* DrawTrSurf_SetPnt (const char* theNameStr, void* thePntPtr)
const char* DrawTrSurf_SetPnt2d (const char* theNameStr, void* thePnt2dPtr)
~~~~~
~~~~
Sets the specified geometric object as a value of DRAW interpreter variable with the given name.
- *theNameStr* -- the DRAW interpreter variable name to set.
@ -90,27 +90,27 @@ All these functions are defined in *TKDraw* toolkit and return a string indicati
The following functions are provided by *TKBRep* toolkit and can be used from debugger prompt:
~~~~~
~~~~{.php}
const char* BRepTools_Write (const char* theFileNameStr, void* theShapePtr)
~~~~~
~~~~
Saves the specified shape to a file with the given name.
- *theFileNameStr* -- the name of the file where the shape is saved.
- *theShapePtr* -- a pointer to *TopoDS_Shape* variable.
~~~~~
~~~~{.php}
const char* BRepTools_Dump (void* theShapePtr)
const char* BRepTools_DumpLoc (void* theShapePtr)
~~~~~
~~~~
Dumps shape or its location to cout.
- *theShapePtr* -- a pointer to *TopoDS_Shape* variable.
The following function is provided by *TKMesh* toolkit:
~~~~~
~~~~{.php}
const char* BRepMesh_Dump (void* theMeshHandlePtr, const char* theFileNameStr)
~~~~~
~~~~
Stores mesh produced in parametric space to BREP file.
- *theMeshHandlePtr* -- a pointer to *Handle(BRepMesh_DataStructureOfDelaun)* variable.
@ -118,10 +118,10 @@ Stores mesh produced in parametric space to BREP file.
The following functions are provided by *TKTopTest* toolkit:
~~~~~
~~~~{.php}
const char* MeshTest_DrawLinks(const char* theNameStr, void* theFaceAttr)
const char* MeshTest_DrawTriangles(const char* theNameStr, void* theFaceAttr)
~~~~~
~~~~
Sets the edges or triangles from mesh data structure of type *Handle(BRepMesh_FaceAttribute)* as DRAW interpreter variables, assigning a unique name in the form "<theNameStr>_<index>" to each object.
- *theNameStr* -- the prefix to use in names of objects.
@ -129,9 +129,9 @@ Sets the edges or triangles from mesh data structure of type *Handle(BRepMesh_Fa
The following additional function is provided by *TKGeomBase* toolkit:
~~~~~
~~~~{.php}
const char* GeomTools_Dump (void* theHandlePtr)
~~~~~
~~~~
Dump geometric object to cout.
- *theHandlePtr* -- a pointer to the geometric variable (<i>Handle</i> to *Geom_Geometry* or *Geom2d_Curve* or descendant) to be set.
@ -174,7 +174,7 @@ It is implemented in 'vaspect' and 'boundingbox' commands.
Json output for Bnd_OBB (using command 'bounding v -obb -dumpJson'):
~~~~~
~~~~{.java}
"Bnd_OBB": {
"Center": {
"gp_XYZ": [1, 2, 3]
@ -193,7 +193,7 @@ Json output for Bnd_OBB (using command 'bounding v -obb -dumpJson'):
"HDims[2]": 0,
"IsAABox": 1,
}
~~~~~
~~~~
@section occt_debug_vstudio Using Visual Studio debugger
@ -206,18 +206,18 @@ When the execution is interrupted by a breakpoint, you can use this window to ca
For example, assume that you are debugging a function, where local variable *TopoDS_Edge* *anEdge1* is of interest.
The following set of commands in the Command window will save this edge to file *edge1.brep*, then put it to DRAW variable *e1* and show it maximized in the axonometric DRAW view:
~~~~~
~~~~{.php}
>? ({,,TKBRep.dll}BRepTools_Write)("d:/edge1.brep",(void*)&anEdge1)
0x04a2f234 "d:/edge1.brep"
>? ({,,TKDraw.dll}DBRep_Set)("e1",(void*)&anEdge1)
0x0369eba8 "e1"
>? ({,,TKDraw.dll}Draw_Eval)("donly e1; axo; fit")
0x029a48f0 ""
~~~~~
~~~~
For convenience it is possible to define aliases to commands in this window, for instance (here ">" is prompt provided by the command window; in the Immediate window this symbol should be entered manually):
~~~~~
~~~~{.php}
>alias deval ? ({,,TKDraw}Draw_Eval)
>alias dsetshape ? ({,,TKDraw}DBRep_Set)
>alias dsetcomp ? ({,,TKDraw}DBRep_SetComp)
@ -229,18 +229,18 @@ For convenience it is possible to define aliases to commands in this window, for
>alias dumploc ? ({,,TKBRep}BRepTools_DumpLoc)
>alias dumpmesh ? ({,,TKMesh}BRepMesh_Dump)
>alias dumpgeom ? ({,,TKGeomBase}GeomTools_Dump)
~~~~~
~~~~
Note that aliases are stored in the Visual Studio user's preferences and it is sufficient to define them once on a workstation. With these aliases, the above example can be reproduced easier (note the space symbol after alias name!):
~~~~~
~~~~{.php}
>saveshape ("d:/edge1.brep",(void*)&anEdge1)
0x04a2f234 "d:/edge1.brep"
>dsetshape ("e1",(void*)&anEdge1)
0x0369eba8 "e1"
>deval ("donly e1; axo; fit")
0x029a48f0 ""
~~~~~
~~~~
Note that there is no guarantee that the call will succeed and will not affect the program execution, thus use this feature at your own risk. In particular, the commands interacting with window system (such as *axo*, *vinit*, etc.) are known to cause application crash when the program is built in 64-bit mode. To avoid this, it is recommended to prepare all necessary view windows in advance, and arrange these windows to avoid overlapping with the Visual Studio window, to ensure that they are visible during debug.
@ -252,7 +252,7 @@ In Visual Studio 2005-2010 the rules for this display are defined in file *autoe
### \[AutoExpand\] section
~~~~~
~~~~{.cpp}
; Open CASCADE classes
Standard_Transient=<,t> count=<count,d>
Handle_Standard_Transient=<entity,x> count=<entity->count,d> <,t>
@ -274,11 +274,11 @@ gp_Dir2d=<coord.x,g>, <coord.y,g>
gp_Vec2d=<coord.x,g>, <coord.y,g>
gp_Mat2d={<matrix[0][0],g>,<matrix[0][1],g>}, {<matrix[1][0],g>,<matrix[1][1],g>}
gp_Ax1=loc={<loc.coord.x,g>, <loc.coord.y,g>, <loc.coord.z,g>} vdir={<vdir.coord.x,g>, <vdir.coord.y,g>, <vdir.coord.z,g>}
~~~~~
~~~~
### \[Visualizer\] section
~~~~~
~~~~{.cpp}
; Open CASCADE classes
NCollection_Handle<*> {
@ -342,7 +342,7 @@ Handle_TCollection_HAsciiString {
#array( expr: ((TCollection_HAsciiString*)$e.entity)->myString.mystring[$i],
size: ((TCollection_HAsciiString*)$e.entity)->myString.mylength) ) )
}
~~~~~
~~~~
In Visual Studio 2012 and later, visualizers can be put in a separate file in subdirectory *Visualizers*. See file *occt.natvis* for example.
@ -403,7 +403,10 @@ Example of configuration steps for Ubuntu:
7. Run DRAW and perform tests as usual, keeping in mind that running with sanitizer is much heavier than normal build:
> ./draw.sh relwithdeb <br>
> Draw[]> testgrid -parallel 0
~~~~{.php}
Draw[]> testgrid -parallel 0
~~~~
Note that when running tests under sanitizers, behavior may be different.
Known problems (as of CLang 6.0) are:

View File

@ -380,7 +380,7 @@ https://www.opencascade.com/content/3rd-party-components
| Component | Requirement |
| --------- | ----------- |
| Minimum memory | 512 MB, 1 GB recommended |
| Free disk space (complete installation) | 600 MB approx. |
| Free disk space (complete installation) | 1,5 GB approx. |
On desktop, 3D viewer for optimal performance requires graphics processing unit (GPU) supporting OpenGL 3.3 or above.
Ray tracing requires OpenGL 4.0+ or OpenGL 3.3+ with *GL_ARB_texture_buffer_object_rgb32* extension.

View File

@ -128,7 +128,7 @@ ad696002-5b34-11d1-b5ba-00a0c9064368.Location: PAppStdPlugin
## Implementation of Attribute Transformation in a HXX file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~
\#include <TDF_Attribute.hxx>
\#include <gp_Ax3.hxx>
@ -223,11 +223,11 @@ private:
gp_Pnt myFirstPoint;
gp_Pnt mySecondPoint;
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
## Implementation of Attribute Transformation in a CPP file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
\#include <MyPackage_Transformation.hxx>
//=======================================================================
@ -526,7 +526,7 @@ Standard_OStream& MyPackage_Transformation::Dump(Standard_OStream& anOS) const
MyPackage_Transformation::MyPackage_Transformation():myType(gp_Identity){
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
## Implementation of typical actions with standard OCAF attributes.

View File

@ -160,7 +160,7 @@ drivers for a function driver table with the help of *TFunction_DriverTable* cl
This is an example of the code for iteration and execution of functions.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
// The scope of functions is defined.
Handle(TFunction_Scope) scope = TFunction_Scope::Set( anyLabel );
@ -200,14 +200,14 @@ drivers for a function driver table with the help of *TFunction_DriverTable* cl
} // end of iteration of current functions
} // end of iteration of functions.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
### Example 2: Cylinder function driver
This is an example of the code for a cylinder function driver. To make the things clearer, the methods
<i>\::Arguments()</i> and <i>\::Results()</i> from the base class are also mentioned.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
// A virtual method ::Arguments() returns a list of arguments of the function.
CylinderDriver::Arguments( TDF_LabelList&amp; args )
@ -283,4 +283,4 @@ drivers for a function driver table with the help of *TFunction_DriverTable* cl
return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~

View File

@ -811,7 +811,7 @@ The following example illustrates how to use the GF algorithm:
#### Usage of the GF algorithm on C++ level
~~~~
~~~~{.cpp}
BOPAlgo_Builder aBuilder;
// Setting arguments
TopTools_ListOfShape aLSObjects = …; // Objects
@ -865,7 +865,7 @@ const TopoDS_Shape& aResult = aBuilder.Shape();
#### Usage of the GF algorithm on Tcl level
~~~~
~~~~{.cpp}
# prepare the arguments
box b1 10 10 10
box b2 3 4 5 10 10 10
@ -1199,7 +1199,7 @@ It is based on the General Fuse algorithm, thus all options of the General Fuse
@subsubsection specification__boolean_8_3_1 API
On the low level the Splitter algorithm is implemented in class *BOPAlgo_Splitter*. The usage of this algorithm looks as follows:
~~~~~
~~~~{.cpp}
BOPAlgo_Splitter aSplitter;
// Setting arguments and tools
TopTools_ListOfShape aLSObjects = …; // Objects
@ -1218,12 +1218,12 @@ if (aSplitter.HasErrors()) { //check error status
}
//
const TopoDS_Shape& aResult = aSplitter.Shape(); // result of the operation
~~~~~
~~~~
@subsubsection specification__boolean_8_3_2 DRAW
The command *bsplit* implements the Splitter algorithm in DRAW. Similarly to the *bbuild* command for the General Fuse algorithm, the *bsplit* command should be used after the Pave Filler is filled.
~~~~~
~~~~{.cpp}
# s1 s2 s3 - objects
# t1 t2 t3 - tools
bclearobjects
@ -1232,7 +1232,7 @@ baddobjects s1 s2 s3
baddtools t1 t2 t3
bfillds
bsplit result
~~~~~
~~~~
@subsection specification__boolean_8_4 Examples
@ -1240,7 +1240,7 @@ bsplit result
Splitting a face by the set of edges:
~~~~
~~~~{.cpp}
# draw script for reproducing
bclearobjects
bcleartools
@ -1286,7 +1286,7 @@ bsplit result
Splitting a plate by the set of cylinders:
~~~~
~~~~{.cpp}
# draw script for reproducing:
bclearobjects
bcleartools
@ -2182,7 +2182,7 @@ This option is useful e.g. for building a solid from the faces of one shell or f
#### C++ Level
The usage of the algorithm on the API level:
~~~~
~~~~{.cpp}
BOPAlgo_MakerVolume aMV;
// Set the arguments
TopTools_ListOfShape aLS = …; // arguments
@ -2206,7 +2206,7 @@ const TopoDS_Shape& aResult = aMV.Shape(); // result of the operation
#### Tcl Level
To use the algorithm in Draw the command mkvolume has been implemented. The usage of this command is following:
~~~~
~~~~{.php}
Usage: mkvolume r b1 b2 ... [-c] [-ni] [-ai]
Options:
-c - use this option to have input compounds considered as set of separate arguments (allows passing multiple arguments as one compound);
@ -2309,7 +2309,7 @@ aResult = aCBuilder.Shape(); // the result
#### DRAW usage
The following set of new commands has been implemented to run the algorithm in DRAW Test Harness:
~~~~
~~~~{.php}
bcbuild : Initialization of the Cells Builder. Use: *bcbuild r*
bcadd : Add parts to result. Use: *bcadd r s1 (0,1) s2 (0,1) ... [-m material [-u]]*
bcaddall : Add all parts to result. Use: *bcaddall r [-m material [-u]]*
@ -2320,7 +2320,7 @@ bcmakecontainers : Make containers from the parts added to result. Use: *bcmakec
~~~~
Here is the example of the algorithm use on the DRAW level:
~~~~
~~~~{.php}
psphere s1 15
psphere s2 15
psphere s3 15
@ -2343,7 +2343,7 @@ bcremoveint res
@subsection specification__boolean_10c_Cells_2 Examples
The following simple example illustrates the possibilities of the algorithm working on a cylinder and a sphere intersected by a plane:
~~~~
~~~~{.php}
pcylinder c 10 30
psphere s 15
ttranslate s 0 0 30
@ -2353,7 +2353,7 @@ mkface f p -25 30 -17 17
@figure{/specification/boolean_operations/images/cells_algorithm_001.png,"Arguments",160}
~~~~
~~~~{.php}
bclearobjects
bcleartools
baddobjects c s f
@ -2363,7 +2363,7 @@ bcbuild r
#### 1. Common for all arguments
~~~~
~~~~{.php}
bcremoveall
bcadd res c 1 s 1 f 1
~~~~
@ -2372,7 +2372,7 @@ bcadd res c 1 s 1 f 1
#### 2. Common between cylinder and face
~~~~
~~~~{.php}
bcremoveall
bcadd res f 1 c 1
~~~~
@ -2381,7 +2381,7 @@ bcadd res f 1 c 1
#### 3. Common between cylinder and sphere
~~~~
~~~~{.php}
bcremoveall
bcadd res c 1 s 1
~~~~
@ -2390,7 +2390,7 @@ bcadd res c 1 s 1
#### 4. Fuse of cylinder and sphere
~~~~
~~~~{.php}
bcremoveall
bcadd res c 1 -m 1
bcadd res s 1 -m 1
@ -2401,7 +2401,7 @@ bcremoveint res
#### 5. Parts of the face inside solids - FUSE(COMMON(f, c), COMMON(f, s))
~~~~
~~~~{.php}
bcremoveall
bcadd res f 1 s 1 -m 1
bcadd res f 1 c 1 -m 1
@ -2409,7 +2409,7 @@ bcadd res f 1 c 1 -m 1
@figure{/specification/boolean_operations/images/cells_algorithm_006_1.png,"Parts of the face inside solids",160}
~~~~
~~~~{.php}
bcremoveint res
~~~~
@ -2417,7 +2417,7 @@ bcremoveint res
#### 6. Part of the face outside solids
~~~~
~~~~{.php}
bcremoveall
bcadd res f 1 c 0 s 0
~~~~
@ -2426,7 +2426,7 @@ bcadd res f 1 c 0 s 0
#### 7. Fuse operation (impossible using standard Boolean Fuse operation)
~~~~
~~~~{.php}
bcremoveall
bcadd res c 1 -m 1
bcadd res s 1 -m 1
@ -2788,7 +2788,7 @@ For setting the Gluing options in DRAW it is necessary to call the <i>bglue</i>
* 1 - for partial coincidence;
* 2 - for full coincidence
~~~~
~~~~{.php}
bglue 1
~~~~
@ -2836,7 +2836,7 @@ To enable the safe processing mode for the operation in DRAW, it is necessary to
* 0 - default value, the safe mode is switched off;
* 1 - the safe mode will be switched on.
~~~~
~~~~{.php}
bnondestructive 1
~~~~
@ -2867,7 +2867,7 @@ To enable/disable the classification of the solids in DRAW, it is necessary to c
* 0 - disabling the classification;
* 1 - default value, enabling the classification.
~~~~
~~~~{.php}
bcheckinverted 0
~~~~
@ -2893,7 +2893,7 @@ aGF.SetUseOBB(Standard_True);
To enable/disable the usage of OBB in the operation in DRAW it is necessary to call the *buseobb* command with the appropriate value:
* 0 - disabling the usage of OBB;
* 1 - enabling the usage of OBB.
~~~~
~~~~{.php}
buseobb 1
~~~~
@ -2919,7 +2919,7 @@ Note that messages corresponding to errors and warnings are defined in resource
These messages can be localized; for that put translated version to separate file and load it in the application by call to *Message_MsgFile::Load()* .
Here is the example of how to use this system:
~~~~~
~~~~{.php}
BOPAlgo_PaveFiller aPF;
aPF.SetArguments(...);
aPF.Perform();
@ -2934,12 +2934,12 @@ if (aPF.HasErrors()) {
}
...
}
~~~~~
~~~~
DRAW commands executing Boolean operations output errors and warnings generated by these operations in textual form.
Additional option allows saving shapes for which warnings have been generated, as DRAW variables.
To activate this option, run command *bdrawwarnshapes* with argument 1 (or with 0 to deactivate):
~~~~
~~~~{.php}
bdrawwarnshapes 1
~~~~
@ -2978,7 +2978,7 @@ But if the faces are fully coinciding, the result must be empty, and both faces
Example of the overlapping faces:
~~~~
~~~~{.php}
plane p 0 0 0 0 0 1
mkface f1 p -10 10 -10 10
mkface f2 p 0 20 -10 10
@ -3005,7 +3005,7 @@ Thus, each of the input edges will be Modified into its two splits.
But in the CUT operation on the same edges, the tool edge will be Deleted from the result and, thus, will not have any Modified shapes.
Example of the intersecting edges:
~~~~
~~~~{.php}
line l1 0 0 0 1 0 0
mkedge e1 l1 -10 10
@ -3051,7 +3051,7 @@ Two intersecting edges will both have the intersection vertices Generated from t
As for the operation with intersecting faces, consider the following example:
~~~~
~~~~{.php}
plane p1 0 0 0 0 0 1
mkface f1 p1 -10 10 -10 10
@ -3115,7 +3115,7 @@ For controlling this possibility in DRAW the command **bsimplify** has been impl
Here is the simple example of simplification of the result of Fuse operation of two boxes:
~~~~
~~~~{.php}
bsimplify -f 1
box b1 10 10 15
@ -3173,7 +3173,7 @@ The following example illustrates how to use General Fuse operator:
#### C++ Level
~~~~
~~~~{.cpp}
#include <TopoDS_Shape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <BRepAlgoAPI_BuilderAlgo.hxx>
@ -3205,7 +3205,7 @@ The following example illustrates how to use General Fuse operator:
#### Tcl Level
~~~~
~~~~{.php}
# prepare the arguments
box b1 10 10 10
box b2 3 4 5 10 10 10
@ -3231,7 +3231,7 @@ The following example illustrates how to use the Splitter operator:
#### C++ Level
~~~~
~~~~{.cpp}
#include <TopoDS_Shape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <BRepAlgoAPI_Splitter.hxx>
@ -3265,7 +3265,7 @@ const TopoDS_Shape& aResult = aSplitter.Shape();
#### Tcl Level
~~~~
~~~~{.php}
# prepare the arguments
# objects
box b1 10 10 10
@ -3297,7 +3297,7 @@ The following example illustrates how to use Common operation:
#### C++ Level
~~~~
~~~~{.cpp}
#include <TopoDS_Shape.hxx>
#include <TopTools_ListOfShape.hxx>
#include < BRepAlgoAPI_Common.hxx>
@ -3336,7 +3336,7 @@ The following example illustrates how to use Common operation:
#### Tcl Level
~~~~
~~~~{.php}
# prepare the arguments
box b1 10 10 10
box b2 7 0 4 10 10 10
@ -3364,7 +3364,7 @@ The following example illustrates how to use Fuse operation:
#### C++ Level
~~~~
~~~~{.cpp}
#include <TopoDS_Shape.hxx>
#include <TopTools_ListOfShape.hxx>
#include < BRepAlgoAPI_Fuse.hxx>
@ -3403,7 +3403,7 @@ The following example illustrates how to use Fuse operation:
#### Tcl Level
~~~~
~~~~{.php}
# prepare the arguments
box b1 10 10 10
box b2 7 0 4 10 10 10
@ -3431,7 +3431,7 @@ The following example illustrates how to use Cut operation:
#### C++ Level
~~~~
~~~~{.cpp}
#include <TopoDS_Shape.hxx>
#include <TopTools_ListOfShape.hxx>
#include < BRepAlgoAPI_Cut.hxx>
@ -3470,7 +3470,7 @@ The following example illustrates how to use Cut operation:
#### Tcl Level
~~~~
~~~~{.php}
# prepare the arguments
box b1 10 10 10
box b2 7 0 4 10 10 10
@ -3499,7 +3499,7 @@ The following example illustrates how to use Section operation:
#### C++ Level
~~~~
~~~~{.cpp}
#include <TopoDS_Shape.hxx>
#include <TopTools_ListOfShape.hxx>
#include < BRepAlgoAPI_Section.hxx>
@ -3538,7 +3538,7 @@ The following example illustrates how to use Section operation:
#### Tcl Level
~~~~
~~~~{.php}
# prepare the arguments
box b1 10 10 10
box b2 3 4 5 10 10 10

View File

@ -35,12 +35,12 @@ Each of these methods has two arguments:
The following sample code reads a shape from ASCII file and writes it to a binary one:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Shape aShape;
if (BRepTools::Read (aShape, "source_file.txt")) {
BinTools::Write (aShape, "result_file.bin");
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@section specification__brep_format_3 Format Common Structure
@ -250,7 +250,7 @@ The example record is interpreted as a line which passes through a point *P*=(1
**BNF-like Definition**
~~~~
~~~~{.cpp}
<3D curve record 2> = "2" <_> <3D circle center> <_> <3D circle N> <_> <3D circle Dx> <_> <3D circle Dy> <_> <3D circle radius> <_\n>;
<3D circle center> = <3D point>;
@ -283,7 +283,7 @@ The example record is interpreted as a circle which has its center *P*=(1, 2, 3
**BNF-like Definition**
~~~~
~~~~{.cpp}
<3D curve record 3> = "3" <_> <3D ellipse center> <_> <3D ellipse N> <_> <3D ellipse Dmaj> <_> <3D ellipse Dmin> <_> <3D ellipse Rmaj> <_> <3D ellipse Rmin> <_\n>;
<3D ellipse center> = <3D point>;
@ -318,7 +318,7 @@ The example record is interpreted as an ellipse which has its center *P*=(1, 2,
**BNF-like Definition**
~~~~
~~~~{.cpp}
<3D curve record 4> = "4" <_> <3D parabola origin> <_> <3D parabola N> <_> <3D parabola Dx> <_> <3D parabola Dy> <_> <3D parabola focal length> <_\n>;
<3D parabola origin> = <3D point>;
@ -352,7 +352,7 @@ The example record is interpreted as a parabola in plane which passes through a
**BNF-like Definition**
~~~~
~~~~{.cpp}
<3D curve record 5> = "5" <_> <3D hyperbola origin> <_> <3D hyperbola N> <_> <3D hyperbola Dx> <_> <3D hyperbola Dy> <_> <3D hyperbola Kx> <_> <3D hyperbola Ky> <_\n>;
<3D hyperbola origin> = <3D point>;
@ -428,7 +428,7 @@ The example record is interpreted as a Bezier curve with a rational flag *r*=1,
**BNF-like Definition**
~~~~
~~~~{.cpp}
<3D curve record 7> = "7" <_> <3D B-spline rational flag> <_> "0" <_> <3D B-spline degree> <_>
<3D B-spline pole count> <_> <3D B-spline multiplicity knot count> <3D B-spline weight poles>
<_\n> <3D B-spline multiplicity knots> <_\n>;
@ -492,7 +492,7 @@ The example record is interpreted as a B-spline curve with a rational flag *r*=
**BNF-like Definition**
~~~~
~~~~{.cpp}
<3D curve record 8> = "8" <_> <3D trimmed curve u min> <_> <3D trimmed curve u max> <_\n> <3D curve record>;
<3D trimmed curve u min> = <real>;
@ -764,7 +764,7 @@ where @f$ V(v)=(5,2,0)+4 \cdot (cos(v) \cdot (1,0,0)+sin(v) \cdot (0,1,0)), V_{D
**BNF-like Definition**
~~~~
~~~~{.cpp}
<surface record 8> = "8" <_> <Bezier surface u rational flag> <_> <Bezier surface v rational flag> <_> <Bezier surface u degree> <_> <Bezier surface v degree> <_>
<Bezier surface weight poles>;
@ -1076,7 +1076,7 @@ The example record is interpreted as a line which passes through a point *P*=(3
**BNF-like Definition**
~~~~
~~~~{.cpp}
<2D curve record 2> = "2" <_> <2D circle center> <_> <2D circle Dx> <_> <2D circle Dy> <_> <2D circle radius> <_\n>;
<2D circle center> = <2D point>;
@ -1247,7 +1247,7 @@ The example record is interpreted as a Bezier curve with a rational flag *r*=1,
**BNF-like Definition**
~~~~
~~~~{.cpp}
<2D curve record 7> = "7" <_> <2D B-spline rational flag> <_> "0" <_> <2D B-spline degree> <_> <2D B-spline pole count> <_> <2D B-spline multiplicity knot count> <2D B-spline weight poles> <_\n> <2D B-spline multiplicity knots> <_\n>;
<2D B-spline rational flag> = <flag>;
@ -1430,7 +1430,7 @@ The example record describes a polyline from *m*=2 nodes with a parameter prese
**BNF-like Definition**
~~~~
~~~~{.cpp}
<triangulations> = <triangulation header> <_\n> <triangulation records>;
<triangulation header> = "Triangulations" <_> <triangulation count>;
@ -1785,7 +1785,7 @@ The usage of \<vertex data representation u parameter\> *U* is described belo
**BNF-like Definition**
~~~~
~~~~{.cpp}
<edge data> = <_> <edge data tolerance> <_> <edge data same parameter flag> <_> edge data same range flag> <_> <edge data degenerated flag> <_\n> <edge data representations>;
<edge data tolerance> = <real>;
@ -1855,7 +1855,7 @@ Flags \<edge data same parameter flag\>, \<edge data same range flag\> and \<edg
**BNF-like Definition**
~~~~
~~~~{.cpp}
<face data> = <face data natural restriction flag> <_> <face data tolerance> <_> <surface number> <_> <location number> <\n> ["2" <_> <triangulation number>];
<face data natural restriction flag> = <flag>;

View File

@ -66,19 +66,19 @@ To choose the best class for this application, consider the following:
Since all the points you will define are only used to create the profile's curves, an object with a limited lifetime will do. Choose the *gp_Pnt* class.
To instantiate a *gp_Pnt* object, just specify the X, Y, and Z coordinates of the points in the global Cartesian coordinate system:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Pnt aPnt1(-myWidth / 2., 0, 0);
gp_Pnt aPnt2(-myWidth / 2., -myThickness / 4., 0);
gp_Pnt aPnt3(0, -myThickness / 2., 0);
gp_Pnt aPnt4(myWidth / 2., -myThickness / 4., 0);
gp_Pnt aPnt5(myWidth / 2., 0, 0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Once your objects are instantiated, you can use methods provided by the class to access and modify its data. For example, to get the X coordinate of a point:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Standard_Real xValue1 = aPnt1.X();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection OCCT_TUTORIAL_SUB2_2 Profile: Defining the Geometry
With the help of the previously defined points, you can compute a part of the bottle's profile geometry. As shown in the figure below, it will consist of two segments and one arc.
@ -95,15 +95,15 @@ This is because the *GC* provides two algorithm classes which are exactly what i
Both of these classes return a *Geom_TrimmedCurve* manipulated by handle. This entity represents a base curve (line or circle, in our case), limited between two of its parameter values. For example, circle C is parameterized between 0 and 2PI. If you need to create a quarter of a circle, you create a *Geom_TrimmedCurve* on C limited between 0 and M_PI/2.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Handle(Geom_TrimmedCurve) aArcOfCircle = GC_MakeArcOfCircle(aPnt2,aPnt3,aPnt4);
Handle(Geom_TrimmedCurve) aSegment1 = GC_MakeSegment(aPnt1, aPnt2);
Handle(Geom_TrimmedCurve) aSegment2 = GC_MakeSegment(aPnt4, aPnt5);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
All *GC* classes provide a casting method to obtain a result automatically with a function-like call. Note that this method will raise an exception if construction has failed. To handle possible errors more explicitly, you may use the *IsDone* and *Value* methods. For example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
GC_MakeSegment mkSeg (aPnt1, aPnt2);
Handle(Geom_TrimmedCurve) aSegment1;
if(mkSegment.IsDone()){
@ -112,7 +112,7 @@ All *GC* classes provide a casting method to obtain a result automatically with
else {
// handle error
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection OCCT_TUTORIAL_SUB2_3 Profile: Defining the Topology
@ -144,18 +144,18 @@ Referring to the previous table, to build the profile, you will create:
However, the *TopoDS* package provides only the data structure of the topological entities. Algorithm classes available to compute standard topological objects can be found in the *BRepBuilderAPI* package.
To create an edge, you use the BRepBuilderAPI_MakeEdge class with the previously computed curves:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Edge aEdge1 = BRepBuilderAPI_MakeEdge(aSegment1);
TopoDS_Edge aEdge2 = BRepBuilderAPI_MakeEdge(aArcOfCircle);
TopoDS_Edge aEdge3 = BRepBuilderAPI_MakeEdge(aSegment2);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
In Open CASCADE Technology, you can create edges in several ways. One possibility is to create an edge directly from two points, in which case the underlying geometry of this edge is a line, bounded by two vertices being automatically computed from the two input points. For example, aEdge1 and aEdge3 could have been computed in a simpler way:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Edge aEdge1 = BRepBuilderAPI_MakeEdge(aPnt1, aPnt3);
TopoDS_Edge aEdge2 = BRepBuilderAPI_MakeEdge(aPnt4, aPnt5);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
To connect the edges, you need to create a wire with the *BRepBuilderAPI_MakeWire* class. There are two ways of building a wire with this class:
@ -164,9 +164,9 @@ To connect the edges, you need to create a wire with the *BRepBuilderAPI_MakeWir
When building a wire from less than four edges, as in the present case, you can use the constructor directly as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Wire aWire = BRepBuilderAPI_MakeWire(aEdge1, aEdge2, aEdge3);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection OCCT_TUTORIAL_SUB2_4 Profile: Completing the Profile
@ -186,17 +186,17 @@ The first way is to define it from scratch, using its geometric definition:
* X axis is located at (0, 0, 0) - use the *gp_Pnt* class.
* X axis direction is (1, 0, 0) - use the *gp_Dir* class. A *gp_Dir* instance is created out of its X, Y and Z coordinates.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Pnt aOrigin(0, 0, 0);
gp_Dir xDir(1, 0, 0);
gp_Ax1 xAxis(aOrigin, xDir);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
The second and simplest way is to use the geometric constants defined in the gp package (origin, main directions and axis of the global coordinate system). To get the X axis, just call the *gp::OX* method:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Ax1 xAxis = gp::OX();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
As previously explained, the 3D geometric transformation is defined with the *gp_Trsf* class. There are two different ways to use this class:
@ -205,43 +205,43 @@ As previously explained, the 3D geometric transformation is defined with the *gp
Since the simplest approach is always the best one, you should use the SetMirror method with the axis as the center of symmetry.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Trsf aTrsf;
aTrsf.SetMirror(xAxis);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
You now have all necessary data to apply the transformation with the BRepBuilderAPI_Transform class by specifying:
* the shape on which the transformation must be applied.
* the geometric transformation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
BRepBuilderAPI_Transform aBRepTrsf(aWire, aTrsf);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
*BRepBuilderAPI_Transform* does not modify the nature of the shape: the result of the reflected wire remains a wire. But the function-like call or the *BRepBuilderAPI_Transform::Shape* method returns a *TopoDS_Shape* object:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Shape aMirroredShape = aBRepTrsf.Shape();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
What you need is a method to consider the resulting reflected shape as a wire. The *TopoDS* global functions provide this kind of service by casting a shape into its real type. To cast the transformed wire, use the *TopoDS::Wire* method.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Wire aMirroredWire = TopoDS::Wire(aMirroredShape);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
The bottle's profile is almost finished. You have created two wires: *aWire* and *aMirroredWire*. You need to concatenate them to compute a single shape. To do this, you use the *BRepBuilderAPI_MakeWire* class as follows:
* create an instance of *BRepBuilderAPI_MakeWire*.
* add all edges of the two wires by using the *Add* method on this object.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
BRepBuilderAPI_MakeWire mkWire;
mkWire.Add(aWire);
mkWire.Add(aMirroredWire);
TopoDS_Wire myWireProfile = mkWire.Wire();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@section sec3 Building the Body
@ -266,9 +266,9 @@ Your current profile is a wire. Referring to the Shape/Generates table, you need
To create a face, use the *BRepBuilderAPI_MakeFace* class. As previously explained, a face is a part of a surface bounded by a closed wire. Generally, *BRepBuilderAPI_MakeFace* computes a face out of a surface and one or more wires.
When the wire lies on a plane, the surface is automatically computed.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Face myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
The *BRepPrimAPI* package provides all the classes to create topological primitive constructions: boxes, cones, cylinders, spheres, etc. Among them is the *BRepPrimAPI_MakePrism* class. As specified above, the prism is defined by:
@ -277,15 +277,15 @@ The *BRepPrimAPI* package provides all the classes to create topological primiti
You want the solid to be finite, swept along the Z axis and to be myHeight height. The vector, defined with the *gp_Vec* class on its X, Y and Z coordinates, is:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Vec aPrismVec(0, 0, myHeight);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
All the necessary data to create the main body of your bottle is now available. Just apply the *BRepPrimAPI_MakePrism* class to compute the solid:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Shape myBody = BRepPrimAPI_MakePrism(myFaceProfile, aPrismVec);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection OCCT_TUTORIAL_SUB3_2 Applying Fillets
@ -305,9 +305,9 @@ To apply fillets on the edges of a shape, you use the *BRepFilletAPI_MakeFillet*
* Add the fillet descriptions (an edge and a radius) using the *Add* method (you can add as many edges as you need).
* Ask for the resulting filleted shape with the *Shape* method.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
BRepFilletAPI_MakeFillet mkFillet(myBody);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
To add the fillet description, you need to know the edges belonging to your shape. The best solution is to explore your solid to retrieve its edges. This kind of functionality is provided with the *TopExp_Explorer* class, which explores the data structure described in a *TopoDS_Shape* and extracts the sub-shapes you specifically need.
Generally, this explorer is created by providing the following information:
@ -315,9 +315,9 @@ Generally, this explorer is created by providing the following information:
* the shape to explore
* the type of sub-shapes to be found. This information is given with the *TopAbs_ShapeEnum* enumeration.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopExp_Explorer anEdgeExplorer(myBody, TopAbs_EDGE);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
An explorer is usually applied in a loop by using its three main methods:
@ -326,26 +326,26 @@ An explorer is usually applied in a loop by using its three main methods:
* *Next()* to move onto the next sub-shape to explore.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
while(anEdgeExplorer.More()){
TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExplorer.Current());
//Add edge to fillet algorithm
...
anEdgeExplorer.Next();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
In the explorer loop, you have found all the edges of the bottle shape. Each one must then be added in the *BRepFilletAPI_MakeFillet* instance with the *Add()* method. Do not forget to specify the radius of the fillet along with it.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
mkFillet.Add(myThickness / 12., anEdge);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Once this is done, you perform the last step of the procedure by asking for the filleted shape.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
myBody = mkFillet.Shape();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection OCCT_TUTORIAL_SUB3_3 Adding the Neck
@ -358,31 +358,31 @@ To add a neck to the bottle, you will create a cylinder and fuse it to the body.
To position the cylinder, you need to define a coordinate system with the *gp_Ax2* class defining a right-handed coordinate system from a point and two directions - the main (Z) axis direction and the X direction (the Y direction is computed from these two).
To align the neck with the center of the top face, being in the global coordinate system (0, 0, *myHeight*), with its normal on the global Z axis, your local coordinate system can be defined as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Pnt neckLocation(0, 0, myHeight);
gp_Dir neckAxis = gp::DZ();
gp_Ax2 neckAx2(neckLocation, neckAxis);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
To create a cylinder, use another class from the primitives construction package: the *BRepPrimAPI_MakeCylinder* class. The information you must provide is:
* the coordinate system where the cylinder will be located;
* the radius and height.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Standard_Real myNeckRadius = myThickness / 4.;
Standard_Real myNeckHeight = myHeight / 10;
BRepPrimAPI_MakeCylinder MKCylinder(neckAx2, myNeckRadius, myNeckHeight);
TopoDS_Shape myNeck = MKCylinder.Shape();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
You now have two separate parts: a main body and a neck that you need to fuse together.
The *BRepAlgoAPI* package provides services to perform Boolean operations between shapes, and especially: *common* (Boolean intersection), *cut* (Boolean subtraction) and *fuse* (Boolean union).
Use *BRepAlgoAPI_Fuse* to fuse the two shapes:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
myBody = BRepAlgoAPI_Fuse(myBody, myNeck);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection OCCT_TUTORIAL_SUB3_4 Creating a Hollowed Solid
@ -411,11 +411,11 @@ The challenging part in this procedure is to find the face to remove from your s
To find the face with such characteristics, you will once again use an explorer to iterate on all the bottle's faces to find the appropriate one.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
for(TopExp_Explorer aFaceExplorer(myBody, TopAbs_FACE) ; aFaceExplorer.More() ; aFaceExplorer.Next()){
TopoDS_Face aFace = TopoDS::Face(aFaceExplorer.Current());
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
For each detected face, you need to access the geometric properties of the shape: use the *BRep_Tool* class for that. The most commonly used methods of this class are:
@ -423,9 +423,9 @@ For each detected face, you need to access the geometric properties of the shape
* *Curve* to access the 3D curve of an edge;
* *Point* to access the 3D point of a vertex.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
As you can see, the *BRep_Tool::Surface* method returns an instance of the *Geom_Surface* class manipulated by handle. However, the *Geom_Surface* class does not provide information about the real type of the object *aSurface*, which could be an instance of *Geom_Plane*, *Geom_CylindricalSurface*, etc.
All objects manipulated by handle, like *Geom_Surface*, inherit from the *Standard_Transient* class which provides two very useful methods concerning types:
@ -436,52 +436,52 @@ All objects manipulated by handle, like *Geom_Surface*, inherit from the *Standa
DynamicType returns the real type of the object, but you need to compare it with the existing known types to determine whether *aSurface* is a plane, a cylindrical surface or some other type.
To compare a given type with the type you seek, use the *STANDARD_TYPE* macro, which returns the type of a class:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
if(aSurface->DynamicType() == STANDARD_TYPE(Geom_Plane)){
//
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
If this comparison is true, you know that the *aSurface* real type is *Geom_Plane*. You can then convert it from *Geom_Surface* to *Geom_Plane* by using the *DownCast()* method provided by each class inheriting *Standard_Transient*. As its name implies, this static method is used to downcast objects to a given type with the following syntax:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurface);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Remember that the goal of all these conversions is to find the highest face of the bottle lying on a plane. Suppose that you have these two global variables:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Face faceToRemove;
Standard_Real zMax = -1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
You can easily find the plane whose origin is the biggest in Z knowing that the location of the plane is given with the *Geom_Plane::Location* method. For example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Pnt aPnt = aPlane->Location();
Standard_Real aZ = aPnt.Z();
if(aZ > zMax){
zMax = aZ;
faceToRemove = aFace;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
You have now found the top face of the neck. Your final step before creating the hollowed solid is to put this face in a list. Since more than one face can be removed from the initial solid, the *BRepOffsetAPI_MakeThickSolid* constructor takes a list of faces as arguments.
Open CASCADE Technology provides many collections for different kinds of objects: see *TColGeom* package for collections of objects from *Geom* package, *TColgp* package for collections of objects from gp package, etc.
The collection for shapes can be found in the *TopTools* package. As *BRepOffsetAPI_MakeThickSolid* requires a list, use the *TopTools_ListOfShape* class.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopTools_ListOfShape facesToRemove;
facesToRemove.Append(faceToRemove);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
All the necessary data are now available so you can create your hollowed solid by calling the *BRepOffsetAPI_MakeThickSolid* MakeThickSolidByJoin method:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
BRepOffsetAPI_MakeThickSolid BodyMaker;
BodyMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3);
myBody = BodyMaker.Shape();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@section sec4 Building the Threading
@ -504,11 +504,11 @@ Using the same coordinate system *neckAx2* used to position the neck, you create
Notice that one of the cylindrical surfaces is smaller than the neck. There is a good reason for this: after the thread creation, you will fuse it with the neck. So, we must make sure that the two shapes remain in contact.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Handle(Geom_CylindricalSurface) aCyl1 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 0.99);
Handle(Geom_CylindricalSurface) aCyl2 = new Geom_CylindricalSurface(neckAx2, myNeckRadius * 1.05);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection OCCT_TUTORIAL_SUB4_2 Defining 2D Curves
@ -564,11 +564,11 @@ To use 2D primitive geometry types of Open CASCADE Technology for defining a poi
* To define a 2D direction (unit vector) from its X and Y coordinates, use the gp_Dir2d class. The coordinates will automatically be normalized.
* To define a 2D right-handed coordinate system, use the *gp_Ax2d* class, which is computed from a point (origin of the coordinate system) and a direction - the X direction of the coordinate system. The Y direction will be automatically computed.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Pnt2d aPnt(2. * M_PI, myNeckHeight / 2.);
gp_Dir2d aDir(2. * M_PI, myNeckHeight / 4.);
gp_Ax2d anAx2d(aPnt, aDir);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
You will now define the curves. As previously mentioned, these thread profiles are computed on two cylindrical surfaces. In the following figure, curves on the left define the base (on *aCyl1* surface) and the curves on the right define the top of the thread's shape (on *aCyl2* surface).
@ -588,36 +588,36 @@ Supposing that:
Your ellipses are defined as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Standard_Real aMajor = 2. * M_PI;
Standard_Real aMinor = myNeckHeight / 10;
Handle(Geom2d_Ellipse) anEllipse1 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor);
Handle(Geom2d_Ellipse) anEllipse2 = new Geom2d_Ellipse(anAx2d, aMajor, aMinor / 4);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
To describe portions of curves for the arcs drawn above, you define *Geom2d_TrimmedCurve* trimmed curves out of the created ellipses and two parameters to limit them.
As the parametric equation of an ellipse is P(U) = O + (MajorRadius * cos(U) * XDirection) + (MinorRadius * sin(U) * YDirection), the ellipses need to be limited between 0 and M_PI.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Handle(Geom2d_TrimmedCurve) anArc1 = new Geom2d_TrimmedCurve(anEllipse1, 0, M_PI);
Handle(Geom2d_TrimmedCurve) anArc2 = new Geom2d_TrimmedCurve(anEllipse2, 0, M_PI);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
The last step consists in defining the segment, which is the same for the two profiles: a line limited by the first and the last point of one of the arcs.
To access the point corresponding to the parameter of a curve or a surface, you use the Value or D0 method (meaning 0th derivative), D1 method is for first derivative, D2 for the second one.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Pnt2d anEllipsePnt1 = anEllipse1->Value(0);
gp_Pnt2d anEllipsePnt2;
anEllipse1->D0(M_PI, anEllipsePnt2);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
When creating the bottle's profile, you used classes from the *GC* package, providing algorithms to create elementary geometries.
In 2D geometry, this kind of algorithms is found in the *GCE2d* package. Class names and behaviors are similar to those in *GC*. For example, to create a 2D segment out of two points:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Handle(Geom2d_TrimmedCurve) aSegment = GCE2d_MakeSegment(anEllipsePnt1, anEllipsePnt2);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection OCCT_TUTORIAL_SUB4_3 Building Edges and Wires
@ -637,28 +637,28 @@ Previously, you have built:
To compute the edges out of these curves, once again use the *BRepBuilderAPI_MakeEdge* class. One of its constructors allows you to build an edge out of a curve described in the 2D parametric space of a surface.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Edge anEdge1OnSurf1 = BRepBuilderAPI_MakeEdge(anArc1, aCyl1);
TopoDS_Edge anEdge2OnSurf1 = BRepBuilderAPI_MakeEdge(aSegment, aCyl1);
TopoDS_Edge anEdge1OnSurf2 = BRepBuilderAPI_MakeEdge(anArc2, aCyl2);
TopoDS_Edge anEdge2OnSurf2 = BRepBuilderAPI_MakeEdge(aSegment, aCyl2);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Now, you can create the two profiles of the threading, lying on each surface.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Wire threadingWire1 = BRepBuilderAPI_MakeWire(anEdge1OnSurf1, anEdge2OnSurf1);
TopoDS_Wire threadingWire2 = BRepBuilderAPI_MakeWire(anEdge1OnSurf2, anEdge2OnSurf2);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Remember that these wires were built out of a surface and 2D curves.
One important data item is missing as far as these wires are concerned: there is no information on the 3D curves. Fortunately, you do not need to compute this yourself, which can be a difficult task since the mathematics can be quite complex.
When a shape contains all the necessary information except 3D curves, Open CASCADE Technology provides a tool to build them automatically. In the BRepLib tool package, you can use the *BuildCurves3d* method to compute 3D curves for all the edges of a shape.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
BRepLib::BuildCurves3d(threadingWire1);
BRepLib::BuildCurves3d(threadingWire2);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection OCCT_TUTORIAL_SUB4_4 Creating Threading
@ -675,12 +675,12 @@ The loft function is implemented in the *BRepOffsetAPI_ThruSections* class, whic
* Use the *CheckCompatibility* method to activate (or deactivate) the option that checks whether the wires have the same number of edges. In this case, wires have two edges each, so you can deactivate this option.
* Ask for the resulting loft shape with the Shape method.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
BRepOffsetAPI_ThruSections aTool(Standard_True);
aTool.AddWire(threadingWire1); aTool.AddWire(threadingWire2);
aTool.CheckCompatibility(Standard_False);
TopoDS_Shape myThreading = aTool.Shape();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@section sec5 Building the Resulting Compound
@ -688,13 +688,13 @@ The loft function is implemented in the *BRepOffsetAPI_ThruSections* class, whic
You are almost done building the bottle. Use the *TopoDS_Compound* and *BRep_Builder* classes to build single shape from *myBody* and *myThreading*:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Compound aRes;
BRep_Builder aBuilder;
aBuilder.MakeCompound (aRes);
aBuilder.Add (aRes, myBody);
aBuilder.Add (aRes, myThreading);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Congratulations! Your bottle is complete. Here is the result snapshot of the Tutorial application:
@ -709,7 +709,7 @@ If you want to know more and develop major projects using Open CASCADE Technolog
Complete definition of MakeBottle function (defined in the file src/MakeBottle.cxx of the Tutorial):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Shape MakeBottle(const Standard_Real myWidth, const Standard_Real myHeight,
const Standard_Real myThickness)
{
@ -846,5 +846,5 @@ Complete definition of MakeBottle function (defined in the file src/MakeBottle.c
return aRes;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~

View File

@ -39,7 +39,7 @@ Porting of user applications from an earlier OCCT version to version 6.5 require
Porting of user applications from an earlier OCCT version to version 6.5.1 requires taking into account the following major changes:
* Method *Graphic3d_Structure::Groups()* now returns *Graphic3d_SequenceOfGroup*. If this method has been used, the application code should be updated to iterate another collection type or, if *Graphic3d_HSetOfGroup* is required, to fill its own collection:
~~~~
~~~~{.cpp}
const Graphic3d_SequenceOfGroup& aGroupsSeq = theStructure.Groups();
Handle(Graphic3d_HSetOfGroup) aGroupSet = new Graphic3d_HSetOfGroup();
Standard_Integer aLen = aGroupsSeq.Length();
@ -62,7 +62,7 @@ Porting of user applications from an earlier OCCT version to version 6.5.2 requi
* If the callback mechanism in call_togl_redraw function was used in the application code, it is necessary to revise it to take into account the new callback execution and provide a check of reason value of Aspect_GraphicCallbackStruct in callback methods to confirm that the callback code is executed at the right moment. Now the callbacks are executed before redrawing the underlayer, before redrawing the overlayer and at the end of redrawing. The information about the moment when the callback is invoked is provided with the reason value in form of an additional bit flag <i>(OCC_PRE_REDRAW, OCC_PRE_OVERLAY)</i>. The state of OpenGl changed in callback methods will not be restored automatically, which might lead to unwanted behavior in redrawing procedure.
* The print method used in the application code might need to be revised to take into account the ability to choose between print algorithms: tile and stretch. The stretch algorithm will be selected by default during porting.
* It is recommended to *BRepMesh_DiscretFactory* users, to check *BRepMesh_DiscretFactory::SetDefault()* return value to determine plugin availability / validity. *BRepMesh_DiscretFactory::Discret()* method now returns handle instead of pointer. The code should be updated in the following manner:
~~~~
~~~~{.cpp}
Handle(BRepMesh_DiscretRoot) aMeshAlgo = BRepMesh_DiscretFactory::Get().Discret (theShape, theDeflection, theAngularToler);
if (!aMeshAlgo.IsNull()) {}
~~~~
@ -88,7 +88,7 @@ Porting of user applications from an earlier OCCT version to version 6.5.3 requi
Porting of user applications from an earlier OCCT version to version 6.5.4 requires taking into account the following major changes:
* The code using obsolete classes *Aspect_PixMap, Xw_PixMap* and *WNT_PixMap* should be rewritten implementing class *Image_PixMap*, which is now retrieved by *ToPixMap* methods as argument. A sample code using *ToPixMap* is given below:
~~~~
~~~~{.cpp}
#include <Image_AlienPixMap.hxx>
void dump (Handle(V3d_View)& theView3D)
{
@ -121,7 +121,7 @@ Correspondingly, the code using methods *SetAnimationModeOn(), SetAnimationModeO
* Interactive selection of 2D presentations should be set up inside *ComputeSelection()* virtual method of a custom interactive object class, using standard sensitive entities from *Select3D* package and standard or custom entity owners derived from *SelectMgr_EntityOwner* base.
Refer to the Visualization User's Guide for further details concerning OCCT 3D visualization and selection classes. See also *Viewer2D* OCCT sample application, which shows how 2D drawing can be implemented using TKV3d API.
* Run-time graphic driver library loading mechanism based on *CSF_GraphicShr* environment variable usage has been replaced by explicit linking against *TKOpenGl* library. The code sample below shows how the graphic driver should be created and initialized in the application code:
~~~~
~~~~{.cpp}
// initialize a new viewer with OpenGl graphic driver
Handle(Graphic3d_GraphicDriver) aGraphicDriver =
new OpenGl_GraphicDriver ("TKOpenGl");
@ -264,7 +264,7 @@ Custom Interactive Objects should implement new virtual method *SelectMgr_Select
Now the method *SelectMgr_Selection::Sensitive()* does not return *SelectBasics_SensitiveEntity*. It returns an instance of *SelectMgr_SensitiveEntity*, which belongs to a different class hierarchy (thus *DownCast()* will fail). To access base sensitive it is necessary to use method *SelectMgr_SensitiveEntity::BaseSensitive()*. For example:
~~~~
~~~~{.cpp}
Handle(SelectMgr_Selection) aSelection = anInteractiveObject->Selection (aMode);
for (aSelection->Init(); aSelection->More(); aSelection->Next())
{
@ -286,7 +286,7 @@ The depth and distance to the center of geometry must be calculated for the 3D p
Here is an example of overlap/inclusion test for a box:
~~~~
~~~~{.cpp}
if (!theMgr.IsOverlapAllowed()) // check for inclusion
{
Standard_Boolean isInside = Standard_True;
@ -404,26 +404,26 @@ Most of typical changes required for upgrading code for OCCT 7.0 can be done aut
This tool is a Tcl script, thus Tcl should be available on your workstation to run it.
Example:
~~~~~
~~~~{.php}
$ tclsh
% source <path_to_occt>/adm/upgrade.tcl
% upgrade -recurse -all -src=<path_to_your_sources>
~~~~~
~~~~
On Windows, the helper batch script *upgrade.bat* can be used, provided that Tcl is either available in *PATH*, or configured via *custom.bat* script (for instance, if you use OCCT installed from Windows installer package). Start it from the command prompt:
~~~~~
~~~~
cmd> <path_to_occt>\upgrade.bat -recurse -all -inc=<path_to_occt>\inc -src=<path_to_your_sources> [options]
~~~~~
~~~~
Run the upgrade tool without arguments to see the list of available options.
The upgrade tool performs the following changes in the code.
1. Replaces macro *DEFINE_STANDARD_RTTI* by *DEFINE_STANDARD_RTTIEXT*, with second argument indicating base class for the main argument class (if inheritance is recognized by the script):
~~~~~
~~~~{.cpp}
DEFINE_STANDARD_RTTI(Class) -> DEFINE_STANDARD_RTTIEXT(Class, Base)
~~~~~
~~~~
@note If macro *DEFINE_STANDARD_RTTI* with two arguments (used in intermediate development versions of OCCT 7.0) is found, the script will convert it to either *DEFINE_STANDARD_RTTIEXT* or *DEFINE_STANDARD_RTTI_INLINE*.
The former case is used if current file is header and source file with the same name is found in the same folder.
@ -431,50 +431,50 @@ DEFINE_STANDARD_RTTI(Class) -> DEFINE_STANDARD_RTTIEXT(Class, Base)
The latter variant defines all methods for RTTI as inline, and does not require *IMPLEMENT_STANDARD_RTTIEXT* macro.
2. Replaces forward declarations of collection classes previously generated from CDL generics (defined in *TCollection* package) by inclusion of the corresponding header:
~~~~~
~~~~{.cpp}
class TColStd_Array1OfReal; -> #include <TColStd_Array1OfReal.hxx>
~~~~~
~~~~
3. Replaces underscored names of *Handle* classes by usage of a macro:
~~~~~
~~~~{.cpp}
Handle_Class -> Handle(Class)
~~~~~
~~~~
This change is not applied if the source or header file is recognized as containing the definition of Qt class with signals or slots, to avoid possible compilation errors of MOC files caused by inability of MOC to recognize macros (see https://doc.qt.io/qt-4.8/signalsandslots.html).
The file is considered as defining a Qt object if it contains strings *Q_OBJECT* and either *slots:* or *signals:*.
4. Removes forward declarations of classes with names <i>Handle(C)</i> or *Handle_C*, replacing them either by forward declaration of its argument class, or (for files defining Qt objects) <i>\#include</i> statement for a header with the name of the argument class and extension .hxx:
~~~~~
~~~~{.cpp}
class Handle(TColStd_HArray1OfReal); -> #include <TColStd_HArray1OfReal.hxx>
~~~~~
~~~~
5. Removes <i> \#includes </i> of files <i>Handle_...hxx</i> that have disappeared in OCCT 7.0:
~~~~~
~~~~{.cpp}
#include <Handle_Geom_Curve.hxx> ->
~~~~~
~~~~
6. Removes *typedef* statements that use *Handle* macro to generate the name:
~~~~~
~~~~{.cpp}
typedef NCollection_Handle<Message_Msg> Handle(Message_Msg); ->
~~~~~
~~~~
7. Converts C-style casts applied to Handles into calls to <i>DownCast()</i> method:
~~~~~
~~~~{.cpp}
((Handle(A)&)b) -> Handle(A)::DownCast(b)
(Handle(A)&)b -> Handle(A)::DownCast(b)
(*((Handle(A)*)&b)) -> Handle(A)::DownCast(b)
*((Handle(A)*)&b) -> Handle(A)::DownCast(b)
(*(Handle(A)*)&b) -> Handle(A)::DownCast(b)
~~~~~
~~~~
8. Moves <i>Handle()</i> macro out of namespace scope:
~~~~~
~~~~{.cpp}
Namespace::Handle(Class) -> Handle(Namespace::Class)
~~~~~
~~~~
9. Converts local variables of reference type, which are initialized by a temporary object returned by call to <i>DownCast()</i>, to the variables of non-reference type (to avoid using references to destroyed memory):
~~~~~
~~~~{.cpp}
const Handle(A)& a = Handle(B)::DownCast (b); -> Handle(A) a (Handle(B)::DownCast (b));
~~~~~
~~~~
10. Adds <i>\#include</i> for all classes used as argument to macro <i>STANDARD_TYPE()</i>, except for already included ones;
@ -487,9 +487,9 @@ Namespace::Handle(Class) -> Handle(Namespace::Class)
As long as the upgrade routine runs, some information messages are sent to the standard output.
In some cases the warnings or errors like the following may appear:
~~~~~
~~~~
Error in {HEADER_FILE}: Macro DEFINE_STANDARD_RTTI used for class {CLASS_NAME} whose declaration is not found in this file, cannot fix
~~~~~
~~~~
Be sure to check carefully all reported errors and warnings, as the corresponding code will likely require manual corrections.
In some cases these messages may help you to detect errors in your code, for instance, cases where *DEFINE_STANDARD_RTTI* macro is used with incorrect class name as an argument.
@ -506,12 +506,12 @@ The use of handle objects (construction, comparison using operators == or !=, us
For example, the following lines will fail to compile if *Geom_Line.hxx* is not included:
~~~~~
~~~~{.cpp}
Handle(Geom_Line) aLine = 0;
if (aLine != aCurve) {...}
if (aCurve->IsKind(STANDARD_TYPE(Geom_Line)) {...}
aLine = Handle(Geom_Line)::DownCast (aCurve);
~~~~~
~~~~
Note that it is not necessary to include header of the class to declare Handle to it.
However, if you define a class *B* that uses Handle(*A*) in its fields, or contains a method returning Handle(*A*), it is advisable to have header defining *A* included in the header of *B*.
@ -523,31 +523,31 @@ This issue appears in the compilers that do not support default arguments in tem
The problem is that operator <i> const handle<T2>& </i> is defined for any type *T2*, thus the compiler cannot make the right choice.
Example:
~~~~~
~~~~{.cpp}
void func (const Handle(Geom_Curve)&);
void func (const Handle(Geom_Surface)&);
Handle(Geom_TrimmedCurve) aCurve = new Geom_TrimmedCurve (...);
func (aCurve); // ambiguity error in VC++ 10
~~~~~
~~~~
Note that this problem can be avoided in many cases if macro *OCCT_HANDLE_NOCAST* is used, see @ref upgrade_occt700_cdl_nocast "below".
To resolve this ambiguity, change your code so that argument type should correspond exactly to the function signature.
In some cases this can be done by using the relevant type for the corresponding variable, like in the example above:
~~~~~
~~~~{.cpp}
Handle(Geom_Curve) aCurve = new Geom_TrimmedCurve (...);
~~~~~
~~~~
Other variants consist in assigning the argument to a local variable of the correct type and using the direct cast or constructor:
~~~~~
~~~~{.cpp}
const Handle(Geom_Curve)& aGCurve (aTrimmedCurve);
func (aGCurve); // OK - argument has exact type
func (static_cast(aCurve)); // OK - direct cast
func (Handle(Geom_Curve)(aCurve)); // OK - temporary handle is constructed
~~~~~
~~~~
Another possibility consists in defining additional template variant of the overloaded function causing ambiguity, and using *SFINAE* to resolve the ambiguity.
This technique can be illustrated by the definition of the template variant of method <i>IGESData_IGESWriter::Send()</i>.
@ -558,31 +558,31 @@ As the cast of a handle to the reference to another handle to the base type has
For example:
~~~~~
~~~~{.cpp}
Handle(Geom_Geometry) aC = GC_MakeLine (p, v); // compiler error
~~~~~
~~~~
The problem is that the class *GC_MakeLine* has a user-defined conversion to <i>const Handle(Geom_TrimmedCurve)&,</i> which is not the same as the type of the local variable *aC*.
To resolve this, use method <i>Value()</i>:
~~~~~
~~~~{.cpp}
Handle(Geom_Geometry) aC = GC_MakeLine (p, v).Value(); // ok
~~~~~
~~~~
or use variable of the appropriate type:
~~~~~
~~~~{.cpp}
Handle(Geom_TrimmedCurve) aC = GC_MakeLine (p, v); // ok
~~~~~
~~~~
A similar problem appears with GCC compiler, when *const* handle to derived type is used to construct handle to base type via assignment (and in some cases in return statement), for instance:
~~~~~
~~~~{.cpp}
const Handle(Geom_Line) aLine;
Handle(Geom_Curve) c1 = aLine; // GCC error
Handle(Geom_Curve) c2 (aLine); // ok
~~~~~
~~~~
This problem is specific to GCC and it does not appear if macro *OCCT_HANDLE_NOCAST* is used, see @ref upgrade_occt700_cdl_nocast "below".
@ -593,20 +593,20 @@ You might need to clean your code from incorrect use of macros *STANDARD_TYPE*()
1. Explicit definitions of static functions with names generated by macro *STANDARD_TYPE()*, which are artifacts of old implementation of RTTI, should be removed.
Example:
~~~~~
~~~~{.cpp}
const Handle(Standard_Type)& STANDARD_TYPE(math_GlobOptMin)
{
static Handle(Standard_Type) _atype = new Standard_Type ("math_GlobOptMin", sizeof (math_GlobOptMin));
return _atype;
}
~~~~~
~~~~
2. Incorrect location of closing parenthesis of *Handle()* macro that was not detectable in OCCT 6.x will cause a compiler error and must be corrected.
Example (note misplaced closing parenthesis):
~~~~~
~~~~{.cpp}
aBSpline = Handle( Geom2d_BSplineCurve::DownCast(BS->Copy()) );
~~~~~
~~~~
#### Use of class Standard_AncestorIterator
@ -617,20 +617,20 @@ Class *Standard_AncestorIterator* has been removed; use method *Parent()* of *St
Handles in OCCT 7.0 do not have the operator of conversion to <i>Standard_Transient*,</i> which was present in earlier versions.
This is done to prevent possible unintended errors like this:
~~~~~
~~~~{.cpp}
Handle(Geom_Line) aLine = ...;
Handle(Geom_Surface) aSurf = ...;
...
if (aLine == aSurf) {...} // will cause a compiler error in OCCT 7.0, but not OCCT 6.x
~~~~~
~~~~
The places where this implicit cast has been used should be corrected manually.
The typical situation is when Handle is passed to stream:
~~~~~
~~~~{.cpp}
Handle(Geom_Line) aLine = ...;
os << aLine; // in OCCT 6.9.0, resolves to operator << (void*)
~~~~~
~~~~
Call method <i>get()</i> explicitly to output the address of the Handle.
@ -639,24 +639,24 @@ Call method <i>get()</i> explicitly to output the address of the Handle.
Method *DownCast()* in OCCT 7.0 is made templated; if its argument is not a base class, "deprecated" compiler warning is generated.
This is done to prevent possible unintended errors like this:
~~~~~
~~~~{.cpp}
Handle(Geom_Surface) aSurf = ;
Handle(Geom_Line) aLine =
Handle(Geom_Line)::DownCast (aSurf); // will cause a compiler warning in OCCT 7.0, but not OCCT 6.x
~~~~~
~~~~
The places where this cast has been used should be corrected manually.
If down casting is used in a template context where the argument can have the same or unrelated type so that *DownCast()* may be not available in all cases, use C++ *dynamic_cast<>* instead, e.g.:
~~~~~
~~~~{.cpp}
template <class T>
bool CheckLine (const Handle(T) theArg)
{
Handle(Geom_Line) aLine = dynamic_cast<Geom_Line> (theArg.get());
...
}
~~~~~
~~~~
@subsubsection upgrade_occt700_cdl_runtime Possible runtime problems
@ -671,19 +671,19 @@ This problem does not appear if macro *OCCT_HANDLE_NOCAST* is used during compil
Example:
~~~~~
~~~~{.cpp}
// note that DownCast() returns new temporary object!
const Handle(Geom_BoundedCurve)& aBC =
Handle(Geom_TrimmedCurve)::DownCast(aCurve);
aBC->Transform (T); // access violation in OCCT 7.0
~~~~~
~~~~
@subsubsection upgrade_occt700_cdl_nocast Option to avoid cast of handle to reference to base type
In OCCT 6.x and earlier versions the handle classes formed a hierarchy echoing the hierarchy of the corresponding object classes .
This automatically enabled the possibility to use the handle to a derived class in all contexts where the handle to a base class was needed, e.g. to pass it in a function by reference without copying:
~~~~
~~~~{.cpp}
Standard_Boolean GetCurve (Handle(Geom_Curve)& theCurve);
....
Handle(Geom_Line) aLine;
@ -705,13 +705,13 @@ This implies creation of temporary objects and hence may be more expensive at ru
The code that relies on the possibility of casting to base should be amended to always use the handle of argument type in function call and to use *DownCast()* to safely convert the result to the desired type.
For instance, the code from the example below can be changed as follows:
~~~~~
~~~~{.cpp}
Handle(Geom_Line) aLine;
Handle(Geom_Curve) aCurve;
if (GetCurve (aCure) && !(aLine = Handle(Geom_Line)::DownCast (aCurve)).IsNull()) {
// use aLine safely
}
~~~~~
~~~~
@subsubsection upgrade_occt700_cdl_compat Preserving compatibility with OCCT 6.x
@ -724,12 +724,12 @@ If you like to preserve the compatibility of your application code with OCCT ver
3. Define macros *DEFINE_STANDARD_RTTIEXT* and *DEFINE_STANDARD_RTTI_INLINE* when building with previous versions of OCCT, resolving to *DEFINE_STANDARD_RTTI* with single argument
Example:
~~~~~
~~~~{.cpp}
#if OCC_VERSION_HEX < 0x070000
#define DEFINE_STANDARD_RTTIEXT(C1,C2) DEFINE_STANDARD_RTTI(C1)
#define DEFINE_STANDARD_RTTI_INLINE(C1,C2) DEFINE_STANDARD_RTTI(C1)
#endif
~~~~~
~~~~
@subsubsection upgrade_occt700_cdl_wok Applications based on CDL and WOK
@ -768,7 +768,7 @@ The code that used the tools provided by that package should be corrected manual
The recommended approach is to use sorting algorithms provided by STL.
For instance:
~~~~~
~~~~{.cpp}
#include <SortTools_StraightInsertionSortOfReal.hxx>
#include <SortTools_ShellSortOfReal.hxx>
#include <TCollection_CompareOfReal.hxx>
@ -777,15 +777,15 @@ TCollection_Array1OfReal aValues = ...;
...
TCollection_CompareOfReal aCompReal;
SortTools_StraightInsertionSortOfReal::Sort(aValues, aCompReal);
~~~~~
~~~~
can be replaced by:
~~~~~
~~~~{.cpp}
#include <algorithm>
...
TCollection_Array1OfReal aValues = ...;
...
std::stable_sort (aValues.begin(), aValues.end());
~~~~~
~~~~
@subsection upgrade_occt700_2dlayers On-screen objects and ColorScale
@ -802,7 +802,7 @@ Predefined Z-layers *Graphic3d_ZLayerId_TopOSD* and *Graphic3d_ZLayerId_BotOSD*
The property of *V3d_View* storing the global *ColorScale* object has been removed with associated methods *V3d_View::ColorScaleDisplay(), V3d_View::ColorScaleErase(), V3d_View::ColorScaleIsDisplayed()* and *V3d_View::ColorScale()* as well as the classes *V3d_ColorScale, V3d_ColorScaleLayerItem* and *Aspect_ColorScale*.
Here is an example of creating *ColorScale* using the updated API:
~~~~~
~~~~{.cpp}
Handle(AIS_ColorScale) aCS = new AIS_ColorScale();
// configuring
Standard_Integer aWidth, aHeight;
@ -815,13 +815,13 @@ aCS->SetZLayer (Graphic3d_ZLayerId_TopOSD);
aCS->SetTransformPersistence (Graphic3d_TMF_2d, gp_Pnt (-1,-1,0));
aCS->SetToUpdate();
theContextAIS->Display (aCS);
~~~~~
~~~~
To see how 2d objects are implemented in OCCT you can call Draw commands *vcolorscale, vlayerline* or *vdrawtext* (with <i>-2d</i> option).
Draw command *vcolorscale* now requires the name of *ColorScale* object as argument.
To display this object use command *vdisplay*. For example:
~~~~~
~~~~{.php}
pload VISUALIZATION
vinit
vcolorscale cs -demo
@ -832,16 +832,16 @@ vsetdispmode 1
vfit
vlayerline 0 300 300 300 10
vdrawtext t "2D-TEXT" -2d -pos 0 150 0 -color red
~~~~~
~~~~
Here is a small example in C++ illustrating how to display a custom AIS object in 2d:
~~~~~
~~~~{.cpp}
Handle(AIS_InteractiveContext) aContext = ...;
Handle(AIS_InteractiveObject) anObj =...; // create an AIS object
anObj->SetZLayer(Graphic3d_ZLayerId_TopOSD); // display object in overlay
anObj->SetTransformPersistence (Graphic3d_TMF_2d, gp_Pnt (-1,-1,0)); // set 2d flag, coordinate origin is set to down-left corner
aContext->Display (anObj); // display the object
~~~~~
~~~~
@subsection upgrade_occt700_userdraw UserDraw and Visual3d
@ -879,7 +879,7 @@ The functionality previously provided by *Visual3d* package has been redesigned
Old APIs based on global callback functions for creating *UserDraw* objects and for performing custom OpenGL rendering within the view have been dropped.
*UserDraw* callbacks are no more required since *OpenGl_Group* now inherits *Graphic3d_Group* and thus can be accessed directly from *AIS_InteractiveObject*:
~~~~~
~~~~{.cpp}
//! Class implementing custom OpenGL element.
class UserDrawElement : public OpenGl_Element {};
@ -901,12 +901,12 @@ void UserDrawObject::Compute (const Handle(PrsMgr_PresentationManager)& thePrsMg
// invalidate bounding box of the scene
thePrsMgr->StructureManager()->Update();
}
~~~~~
~~~~
To perform a custom OpenGL code within the view, it is necessary to inherit from class *OpenGl_View*.
See the following code sample:
~~~~~
~~~~{.cpp}
//! Custom view.
class UserView : public OpenGl_View
{
@ -953,7 +953,7 @@ public:
}
};
~~~~~
~~~~
@subsection upgrade_occt700_localcontext Deprecation of Local Context
@ -1172,22 +1172,22 @@ Class *BRepOffsetAPI_MakeOffsetShape*:
* *BRepOffsetAPI_MakeOffsetShape::PerformByJoin()* - method has been added. This method is old algorithm behaviour.
The code below shows new calling procedure:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
BRepOffsetAPI_MakeOffsetShape OffsetMaker;
OffsetMaker.PerformByJoin(Shape, OffsetValue, Tolerance);
NewShape = OffsetMaker.Shape();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Class *BRepOffsetAPI_MakeThickSolid*:
* *BRepOffsetAPI_MakeThickSolid::BRepOffsetAPI_MakeThickSolid()* - constructor with parameters has been deleted.
* *BRepOffsetAPI_MakeThickSolid::MakeThickSolidByJoin()* - method has been added. This method is old algorithm behaviour.
The code below shows new calling procedure:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
BRepOffsetAPI_MakeThickSolid BodyMaker;
BodyMaker.MakeThickSolidByJoin(myBody, facesToRemove, -myThickness / 50, 1.e-3);
myBody = BodyMaker.Shape();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection upgrade_720_highlight Highlight style
@ -1317,7 +1317,7 @@ One can use this functionality in two ways:
The code example below demonstrates how to read shapes from a storage driver using *StdStorage* class.
~~~~
~~~~{.cpp}
// aDriver should be created and opened for reading
Handle(StdStorage_Data) aData;
@ -1355,7 +1355,7 @@ if (!aRoots.IsNull())
The following code demonstrates how to write shapes in OCCT 7.2.0 using *StdStorage* class.
~~~~
~~~~{.cpp}
// Create a file driver
NCollection_Handle<Storage_BaseDriver> aFileDriver(new FSD_File());
@ -1640,7 +1640,7 @@ The following changes have been introduced in the API of *BRepMesh_IncrementalMe
Example of usage:
Case 1 (explicit parameters):
~~~~
~~~~{.cpp}
#include <IMeshData_Status.hxx>
#include <IMeshTools_Parameters.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
@ -1688,7 +1688,7 @@ In fact, drawing points or lines with lighting applied is a valid use case, but
As aspects for different primitive types have been merged, Graphic3d_Group does no more provide per-type aspect properties.
Existing code relying on old behavior and putting interleaved per-type aspects into single Graphic3d_Group should be updated.
For example, the following pseudo-code will not work anymore, because all *SetGroupPrimitivesAspect* calls will setup the same property:
~~~~
~~~~{.cpp}
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect()); //!< overrides previous aspect
@ -1700,7 +1700,7 @@ aGroup->AddPrimitiveArray (aTris);
~~~~
To solve the problem, the code should be modified to either put primitives into dedicated groups (preferred approach), or using *SetPrimitivesAspect* in proper order:
~~~~
~~~~{.cpp}
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
@ -1718,7 +1718,7 @@ Decomposition of Ambient, Diffuse, Specular and Emissive properties has been eli
As result, the following methods of *Graphic3d_MaterialAspect* class have been removed: SetReflectionMode(), SetReflectionModeOn(), Ambient(), Diffuse(), Emissive(), Specular(), SetAmbient(), SetDiffuse(), SetSpecular(), SetEmissive().
Previously, computation of final value required the following code:
~~~~
~~~~{.cpp}
Graphic3d_MaterialAspect theMaterial; Quantity_Color theInteriorColor;
Graphic3d_Vec3 anAmbient (0.0f);
if (theMaterial.ReflectionMode (Graphic3d_TOR_AMBIENT))
@ -1730,7 +1730,7 @@ if (theMaterial.ReflectionMode (Graphic3d_TOR_AMBIENT))
~~~~
New code looks like this:
~~~~
~~~~{.cpp}
Graphic3d_MaterialAspect theMaterial; Quantity_Color theInteriorColor;
Graphic3d_Vec3 anAmbient = theMaterial.AmbientColor();
if (theMaterial.MaterialType (Graphic3d_MATERIAL_ASPECT)) { anAmbient *= (Graphic3d_Vec3 )theInteriorColor; }
@ -1751,7 +1751,7 @@ Existing code should be updated to:
Parameters of *Text* in *Graphic3d_Group* are moved into a new *Graphic3d_Text* class. *AddText* of *Graphic3d_Group* should be used instead of the previous *Text*.
The previous code:
~~~~
~~~~{.cpp}
Standard_Real x, y, z;
theAttachmentPoint.Coord(x,y,z);
theGroup->Text (theText,
@ -1763,7 +1763,7 @@ theGroup->Text (theText,
theAspect->VerticalJustification());
~~~~
should be replaced by the new code:
~~~~
~~~~{.cpp}
Handle(Graphic3d_Text) aText = new Graphic3d_Text (theAspect->Height());
aText->SetText (theText.ToExtString());
aText->SetPosition (theAttachmentPoint);
@ -1927,7 +1927,7 @@ The method Select3D_SensitiveEntity::NbSubElements() has been changed to be cons
@subsection upgrade_750_Booleans Changes in Boolean operations algorithm
* TreatCompound method has been moved from *BOPAlgo_Tools* to *BOPTools_AlgoTools*. Additionally, the map parameter became optional:
~~~~
~~~~{.cpp}
void BOPTools_AlgoTools::TreatCompound (const TopoDS_Shape& theS,
TopTools_ListOfShape& theLS,
TopTools_MapOfShape* theMap = NULL);
@ -2094,25 +2094,25 @@ corresponding type of the message.
The code that used operator << for messenger, should be ported as follows.
Before the change:
~~~~~
~~~~{.cpp}
Handle(Message_Messenger) theMessenger = ...;
theMessenger << "Value = " << anInteger << Message_EndLine;
~~~~~
~~~~
After the change, single-line variant:
~~~~~
~~~~{.cpp}
Handle(Message_Messenger) theMessenger = ...;
theMessenger->SendInfo() << "Value = " << anInteger << std::endl;
~~~~~
~~~~
After the change, extended variant:
~~~~~
~~~~{.cpp}
Handle(Message_Messenger) theMessenger = ...;
Message_Messenger::StreamBuffer aSender = theMessenger->SendInfo();
aSender << "Array: [ ";
for (int i = 0; i < aNb; ++i) { aSender << anArray[i] << " "; }
aSender << "]" << std::endl; // aSender can be used further for other messages
~~~~~
~~~~
@subsection upgrade_750_message_printer Message_Printer interface change
@ -2136,13 +2136,13 @@ provided that each thread deals with its own instance of *TDataStd_Application*
Note that neither *TDataStd_Application* nor *TDocStd_Document* is protected from concurrent access from several threads.
Such protection, if necessary, shall be implemented on the application level.
For an example, access to labels and attributes could be protected by mutex if there is a probability that different threads access the same labels / attributes:
~~~~~
~~~~{.cpp}
{
Standard_Mutex::Sentry aSentry (myMainLabelAccess);
TDF_Label aChildLab = aDocument->Main().NewChild();
TDataStd_Integer::Set(aChildLab, 0);
}
~~~~~
~~~~
@subsection upgrade_750_draw_hotkeys Draw Harness hotkeys
@ -2179,10 +2179,10 @@ Existing code relying on old behavior, if any, shall be rewritten.
Geom_RectangularTrimmedSurface sequentially trimming in U and V directions already no longer loses the first trim.
For example:
~~~~~
~~~~{.cpp}
Handle(Geom_RectangularTrimmedSurface) ST = new Geom_RectangularTrimmedSurface (Sbase, u1, u2, Standard_True); // trim along U
Handle(Geom_RectangularTrimmedSurface) ST1 = new Geom_RectangularTrimmedSurface (ST, v1, v2, Standard_False); // trim along V
~~~~~
~~~~
gives different result.
In current version ST1 - surface trimmed only along V, U trim is removed;
After modification ST1 - surface trimmed along U and V, U trim is kept.

File diff suppressed because one or more lines are too long

View File

@ -183,9 +183,9 @@ A variable of a type manipulated by handle which is not attached to an object is
To reference an object, we instantiate the class with one of its constructors.
For example, in C++:
~~~~~
~~~~{.cpp}
Handle(MyClass) anObject = new MyClass();
~~~~~
~~~~
In Open CASCADE Technology, the Handles are specific classes that are used to safely manipulate objects allocated in the dynamic memory by reference,
providing reference counting mechanism and automatic destruction of the object when it is not referenced.
@ -302,15 +302,15 @@ It provides a reference counter field, inherited by all its descendant classes,
Objects of classes derived (directly or indirectly) from *Transient*, are normally allocated in dynamic memory using operator **new**, and manipulated by handle.
Handle is defined as template class *opencascade::handle<>*.
Open CASCADE Technology provides preprocessor macro *Handle()* that is historically used throughout OCCT code to name a handle:
~~~~~{.cpp}
~~~~{.cpp}
Handle(Geom_Line) aLine; // "Handle(Geom_Line)" is expanded to "opencascade::handle<Geom_Line>"
~~~~~
~~~~
In addition, for most OCCT classes additional *typedef* is defined for a handle, as the name of a class prefixed by *Handle_*.
For instance, the above example can be also coded as:
~~~~~{.cpp}
~~~~{.cpp}
Handle_Geom_Line aLine; // "Handle_Geom_Line" is typedef to "opencascade::handle<Geom_Line>"
~~~~~
~~~~
#### Using a Handle
@ -318,9 +318,9 @@ A handle is characterized by the object it references.
Before performing any operation on a transient object, you must declare the handle.
For example, if Point and Line are two transient classes from the Geom package, you would write:
~~~~~
~~~~{.cpp}
Handle(Geom_Point) p1, p2;
~~~~~
~~~~
Declaring a handle creates a null handle that does not refer to any object.
The handle may be checked to be null by its method *IsNull()*.
To nullify a handle, use method *Nullify()*.
@ -338,7 +338,7 @@ To enable this feature, a class declaration should include the declaration of OC
Header *Standard_Type.hxx* provides two variants of preprocessor macros facilitating this:
* Inline variant, which declares and defines RTTI methods by a single line of code:
~~~~~{.cpp}
~~~~{.cpp}
#include <Geom_Surface.hxx>
class Appli_ExtSurface : public Geom_Surface
{
@ -346,12 +346,12 @@ class Appli_ExtSurface : public Geom_Surface
public:
DEFINE_STANDARD_RTTIEXT(Appli_ExtSurface,Geom_Surface)
};
~~~~~
~~~~
* Out-of line variant, which uses one macro in the declaration (normally in the header file), and another in the implementation (in C++ source):
In *Appli_ExtSurface.hxx* file:
~~~~~{.cpp}
~~~~{.cpp}
#include <Geom_Surface.hxx>
class Appli_ExtSurface : public Geom_Surface
{
@ -359,13 +359,13 @@ class Appli_ExtSurface : public Geom_Surface
public:
DEFINE_STANDARD_RTTIEXT(Appli_ExtSurface,Geom_Surface)
};
~~~~~
~~~~
In *Appli_ExtSurface.cxx* file:
~~~~~{.cpp}
~~~~{.cpp}
#include <Appli_ExtSurface.hxx>
IMPLEMENT_STANDARD_RTTIEXT(Appli_ExtSurface,Geom_Surface)
~~~~~
~~~~
These macros define method *DynamicType()* that returns a type descriptor - handle to singleton instance of the class *Standard_Type* describing the class.
The type descriptor stores the name of the class and the descriptor of its parent class.
@ -375,12 +375,12 @@ Note that while inline version is easier to use, for widely used classes this me
To get the type descriptor for a given class type, use macro *STANDARD_TYPE()* with the name of the class as argument.
Example of usage:
~~~~~{.cpp}
~~~~{.cpp}
if (aCurve->IsKind(STANDARD_TYPE(Geom_Line))) // equivalent to "if (dynamic_cast<Geom_Line>(aCurve.get()) != 0)"
{
...
}
~~~~~
~~~~
#### Type Conformity
@ -390,12 +390,12 @@ Thus, the dynamic type of an object (also called the actual type of an object) c
Consider the class *Geom_CartesianPoint*, a sub-class of *Geom_Point*; the rule of type conformity can be illustrated as follows:
~~~~~
~~~~{.cpp}
Handle(Geom_Point) aPnt1;
Handle(Geom_CartesianPoint) aPnt2;
aPnt2 = new Geom_CartesianPoint();
aPnt1 = aPnt2; // OK, the types are compatible
~~~~~
~~~~
The compiler sees *aPnt1* as a handle to *Geom_Point* though the actual object referenced by *aPnt1* is of the *Geom_CartesianPoint* type.
@ -409,19 +409,19 @@ A handle can be converted explicitly into one of its sub-types if the actual typ
If this is not the case, the handle is nullified (explicit type conversion is sometimes called a "safe cast").
Consider the example below.
~~~~~~
~~~~{.cpp}
Handle(Geom_Point) aPnt1;
Handle(Geom_CartesianPoint) aPnt2, aPnt3;
aPnt2 = new Geom_CartesianPoint();
aPnt1 = aPnt2; // OK, standard assignment
aPnt3 = Handle(Geom_CartesianPoint)::DownCast (aPnt1);
// OK, the actual type of aPnt1 is Geom_CartesianPoint, although the static type of the handle is Geom_Point
~~~~~~
~~~~
If conversion is not compatible with the actual type of the referenced object, the handle which was "cast" becomes null (and no exception is raised).
So, if you require reliable services defined in a sub-class of the type seen by the handle (static type), write as follows:
~~~~~~
~~~~{.cpp}
void MyFunction (const Handle(A) & a)
{
Handle(B) b = Handle(B)::DownCast(a);
@ -432,12 +432,12 @@ void MyFunction (const Handle(A) & a)
// the types are incompatible
}
}
~~~~~~
~~~~
Downcasting is used particularly with collections of objects of different types; however, these objects should inherit from the same root class.
For example, with a sequence of transient objects *TColStd_SequenceOfTransient* and two classes A and B that both inherit from *Standard_Transient*, you get the following syntax:
~~~~~
~~~~{.cpp}
Handle(A) a;
Handle(B) b;
Handle(Standard_Transient) t;
@ -459,17 +459,17 @@ else
{
// the types are incompatible
}
~~~~~
~~~~
@subsubsection occt_fcug_2_2_3 Using Handles to Create Objects
To create an object which is manipulated by handle, declare the handle and initialize it with the standard C++ **new** operator, immediately followed by a call to the constructor.
The constructor can be any of those specified in the source of the class from which the object is instanced.
~~~~~
~~~~{.cpp}
Handle(Geom_CartesianPoint) aPnt;
aPnt = new Geom_CartesianPoint (0, 0, 0);
~~~~~
~~~~
Unlike for a pointer, the **delete** operator does not work on a handle; the referenced object is automatically destroyed when no longer in use.
@ -480,7 +480,7 @@ To invoke a method which acts on the referenced object, you translate this metho
To test or to modify the state of the handle, the method is translated by the *dot* operator.
The example below illustrates how to access the coordinates of an (optionally initialized) point object:
~~~~~
~~~~{.cpp}
Handle(Geom_CartesianPoint) aCentre;
Standard_Real x, y, z;
if (aCentre.IsNull())
@ -488,11 +488,11 @@ if (aCentre.IsNull())
aCentre = new PGeom_CartesianPoint (0, 0, 0);
}
aCentre->Coord (x, y, z);
~~~~~
~~~~
The example below illustrates how to access the type object of a Cartesian point:
~~~~~
~~~~{.cpp}
Handle(Standard_Transient) aPnt = new Geom_CartesianPoint (0., 0., 0.);
if (aPnt->DynamicType() == STANDARD_TYPE(Geom_CartesianPoint))
{
@ -502,7 +502,7 @@ else
{
std::cout << "Type check FAILED\n";
}
~~~~~
~~~~
*Standard_NullObject* exception will be raised if a field or a method of an object is accessed via a *Null* handle.
@ -512,9 +512,9 @@ A class method is called like a static C++ function, i.e. it is called by the na
For example, we can find the maximum degree of a Bezier curve:
~~~~~
~~~~{.cpp}
Standard_Integer aDegree = Geom_BezierCurve::MaxDegree();
~~~~~
~~~~
@subsubsection occt_fcug_2_2_5 Handle deallocation
@ -529,7 +529,7 @@ The object is automatically deleted by the handle when reference counter becomes
The principle of allocation can be seen in the example below.
~~~~~
~~~~{.cpp}
...
{
Handle(TColStd_HSequenceOfInteger) H1 = new TColStd_HSequenceOfInteger();
@ -549,11 +549,11 @@ The principle of allocation can be seen in the example below.
// Here, H1 has 1 reference
}
// Here, H1 has no reference and the referred TColStd_HSequenceOfInteger object is deleted.
~~~~~
~~~~
You can easily cast a reference to the handle object to <i> void* </i> by defining the following:
~~~~
~~~~{.cpp}
void* aPointer;
Handle(Some_Class) aHandle;
// Here only a pointer will be copied
@ -701,12 +701,12 @@ The following paragraphs describe recommended approaches for using exceptions wh
#### "C++ like" Syntax
The following example:
~~~~~
~~~~{.cpp}
throw Standard_DomainError ("Cannot cope with this condition");
~~~~~
~~~~
raises an exception of *Standard_DomainError* type with the associated message "Cannot cope with this condition", the message being optional.
This exception may be caught by a handler of a *Standard_DomainError* type as follows:
~~~~~
~~~~{.cpp}
try
{
OCC_CATCH_SIGNALS
@ -716,7 +716,7 @@ catch (const Standard_DomainError& )
{
// handle Standard_DomainError exceptions here
}
~~~~~
~~~~
#### Regular usage
@ -734,7 +734,7 @@ For example, if you consider the *TCollection_Array1* class used with:
then, the *Value* function may be implemented as follows:
~~~~~
~~~~{.cpp}
Item TCollection_Array1::Value (Standard_Integer theIndex) const
{
// where myR1 and myR2 are the lower and upper bounds of the array
@ -744,7 +744,7 @@ Item TCollection_Array1::Value (Standard_Integer theIndex) const
}
return myContents[theIndex];
}
~~~~~
~~~~
Here validity of the index is first verified using the Lower and Upper functions in order to protect the call.
Normally the caller ensures the index being in the valid range before calling <i>Value()</i>.
@ -752,26 +752,26 @@ In this case the above implementation of *Value* is not optimal since the test d
It is a widely used practice to include that kind of protections in a debug build of the program and exclude in release (optimized) build.
To support this practice, the macros <i>Raise_if()</i> are provided for every OCCT exception class:
~~~~~
~~~~{.cpp}
<ErrorTypeName>_Raise_if(condition, "Error message");
~~~~~
~~~~
where *ErrorTypeName* is the exception type, *condition* is the logical expression leading to the raise of the exception, and *Error message* is the associated message.
The entire call may be removed by defining one of the preprocessor symbols *No_Exception* or <i>No_<ErrorTypeName></i> at compile-time:
~~~~~
~~~~{.cpp}
#define No_Exception // remove all raises
~~~~~
~~~~
Using this syntax, the *Value* function becomes:
~~~~~
~~~~{.cpp}
Item TCollection_Array1::Value (Standard_Integer theIndex) const
{
Standard_OutOfRange_Raise_if(theIndex < myR1 || theIndex > myR2, "index out of range in TCollection_Array1::Value");
return myContents[theIndex];
}
~~~~~
~~~~
@subsubsection occt_fcug_2_4_3 Handling an Exception
@ -788,7 +788,7 @@ The recommended location for it is first statement after opening brace of <i>try
As an example, consider the exceptions of type *Standard_NumericError, Standard_Overflow, Standard_Underflow* and *Standard_DivideByZero*, where *Standard_NumericError* is the parent type of the three others.
~~~~~
~~~~{.cpp}
void f(1)
{
try
@ -805,7 +805,7 @@ void f(1)
// ...
}
}
~~~~~
~~~~
Here, the first handler will catch exceptions of *Standard_Overflow* type
and the second one -- exceptions of *Standard_NumericError* type and all exceptions derived from it, including *Standard_Underflow* and *Standard_DivideByZero*.
@ -813,7 +813,7 @@ and the second one -- exceptions of *Standard_NumericError* type and all excepti
The handlers are checked in order of appearance, from the nearest to the try block to the most distant from it, until one matches the raise expression.
For a try block, it would be a mistake to place a handler for a base exception type ahead of a handler for its derived type since that would ensure that the handler for the derived exception would never be invoked.
~~~~~
~~~~{.cpp}
void f(1)
{
int i = 0;
@ -832,7 +832,7 @@ void f(1)
}
. . .
}
~~~~~
~~~~
The exceptions form a hierarchy tree completely separated from other user defined classes.
One exception of type *Standard_Failure* is the root of the entire exception hierarchy.
@ -841,7 +841,7 @@ It is recommended to set up such a handler in the main routine.
The main routine of a program would look like this:
~~~~~
~~~~{.cpp}
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <iostream>
@ -859,7 +859,7 @@ int main (int argc, char* argv[])
}
return 1;
}
~~~~~
~~~~
Though standard C++ scoping rules and syntax apply to try block and handlers, note that on some platforms Open CASCADE Technology may be compiled in compatibility mode when exceptions are emulated by long jumps (see below).
In this mode it is required that no statement precedes or follows any handler.
@ -921,17 +921,17 @@ Foundation classes provide in the package *Plugin* a method named *Load()*, whic
That method reads the information regarding available plug-ins and their locations from the resource file *Plugin* found by environment variable *CSF_PluginDefaults*:
~~~~~
~~~~
$CSF_PluginDefaults/Plugin
~~~~~
~~~~
The *Load* method looks for the library name in the resource file or registry through its GUID, for example, on UNIX:
~~~~~
~~~~
! METADATADRIVER whose value must be OS or DM.
! FW
a148e300-5740-11d1-a904-080036aaa103.Location: libFWOSPlugin.so
~~~~~
~~~~
Then the *Load* method loads the library according to the rules of the operating system of the host machine (for example, by using environment variables such as *LD_LIBRARY_PATH* with Unix and *PATH* with Windows).
After that it invokes the *PLUGINFACTORY* method to return the object, which supports the required service.
@ -941,13 +941,13 @@ The client may then call the functions supported by this object.
To invoke one of the services provided by the plug-in, you may call the *Plugin::Load()* global function with the *Standard_GUID* of the requested service as follows:
~~~~~{.cpp}
~~~~{.cpp}
Handle(FADriver_PartStorer)::DownCast(PlugIn::Load (yourStandardGUID));
~~~~~
~~~~
Let us take *FAFactory.hxx* and *FAFactory.cxx* as an example:
~~~~~{.cpp}
~~~~{.cpp}
#include <Standard_Macro.hxx>
#include <Standard_GUID.hxx>
#include <Standard_Transient.hxx>
@ -957,9 +957,9 @@ class FAFactory
public:
Standard_EXPORT static Handle(Standard_Transient) Factory (const Standard_GUID& theGUID);
};
~~~~~
~~~~
~~~~~{.cpp}
~~~~{.cpp}
#include <FAFactory.hxx>
#include <FADriver_PartRetriever.hxx>
@ -1004,7 +1004,7 @@ Handle(Standard_Transient) FAFactory::Factory (const Standard_GUID& theGUID)
// export plugin function "PLUGINFACTORY"
PLUGIN(FAFactory)
~~~~~
~~~~
Application might also instantiate a factory by linking to the library and calling *FAFactory::Factory()* directly.
@ -1042,14 +1042,14 @@ These definitions are now obsolete though still can be used, particularly for co
Let see an example of NCollection template class instantiation for a sequence of points in the header file *MyPackage_SequenceOfPnt.hxx* (analogue of *TColgp_SequenceOfPnt*):
~~~~~{.cpp}
~~~~{.cpp}
#include <NCollection_Sequence.hxx>
#include <gp_Pnt.hxx>
typedef NCollection_Sequence<gp_Pnt> MyPackage_SequenceOfPnt;
~~~~~
~~~~
For the case, when sequence itself should be managed by handle, auxiliary macros *DEFINE_HSEQUENCE* can be used:
~~~~~{.cpp}
~~~~{.cpp}
#include <NCollection_Sequence.hxx>
#include <NCollection_DefineHSequence.hxx>
#include <gp_Pnt.hxx>
@ -1057,7 +1057,7 @@ typedef NCollection_Sequence<gp_Pnt> MyPackage_SequenceOfPnt;
DEFINE_HSEQUENCE(MyPackage_HSequenceOfPnt, MyPackage_SequenceOfPnt)
...
Handle(MyPackage_HSequenceOfPnt) aSeq = new MyPackage_HSequenceOfPnt();
~~~~~
~~~~
See more details about available collections in following sections.
@ -1302,7 +1302,7 @@ The common methods of Iterator are:
Usage sample:
~~~~~{.cpp}
~~~~{.cpp}
typedef Ncollection_Sequence<gp_Pnt> MyPackage_SequenceOfPnt;
void Perform (const MyPackage_SequenceOfPnt& theSequence)
{
@ -1312,17 +1312,17 @@ void Perform (const MyPackage_SequenceOfPnt& theSequence)
...
}
}
~~~~~
~~~~
@subsubsection occt_fcug_3_1_5 Allocators
All constructors of *NCollection* classes receive the *Allocator* object as the last parameter.
This is an object of a type managed by Handle, inheriting *NCollection_BaseAllocator*, with the following (mandatory) methods redefined:
~~~~~{.cpp}
~~~~{.cpp}
virtual void* Allocate (const size_t theSize) override;
virtual void Free (void* theAddress) override;
~~~~~
~~~~
It is used internally every time when the collection allocates memory for its item(s) and releases this memory.
The default value of this parameter (empty *Handle*) designates the use of *NCollection_BaseAllocator*, where the functions *Standard::Allocate* and *Standard::Free* are called.
@ -1360,7 +1360,7 @@ Among the best suitable solutions there can be a pointer to an object, handled o
The bounding object may have any dimension and geometry.
The minimal interface of *TheBndType* (besides public empty and copy constructor and operator=) used in NCollection_UBTree algorithm as follows:
~~~~~{.cpp}
~~~~{.cpp}
class MyBndType
{
public:
@ -1373,7 +1373,7 @@ public:
//! Computes the squared maximal linear extent of me (for a box it is the squared diagonal of the box).
Standard_Real SquareExtent() const;
};
~~~~~
~~~~
This interface is implemented in types of Bnd package: *Bnd_Box, Bnd_Box2d, Bnd_B2x, Bnd_B3x*.
@ -1384,7 +1384,7 @@ The quality of a tree is better (considering the speed of searches) if objects a
Instantiation of *NCollection_UBTreeFiller* collects objects to be added, and then adds them at once to the given NCollection_UBTree instance in a random order using the Fisher-Yates algorithm.
Below is the sample code that creates an instance of *NCollection_UBTree* indexed by 2D boxes (Bnd_B2f), then a selection is performed returning the objects whose bounding boxes contain the given 2D point.
~~~~~{.cpp}
~~~~{.cpp}
typedef NCollection_UBTree<MyData, Bnd_B2f> UBTree;
typedef NCollection_List<MyData> ListOfSelected;
//! Tree Selector type
@ -1426,7 +1426,7 @@ aTreeFiller.Fill();
MyTreeSelector aSel (aPoint2d);
aTree.Select (aSel);
const ListOfSelected& aSelected = aSel.ListAccepted();
~~~~~
~~~~
##### NCollection_CellFilter
@ -1438,10 +1438,10 @@ while search with NCollection_UBTree provides logarithmic law access time.
Packages *TShort*, *TColGeom*, *TColGeom2d*, *TColStd*, *TColgp* provide template instantiations (typedefs) of *NCollection* templates to standard OCCT types.
Classes with *H* prefix in name are handle-based variants and inherit Standard_Transient.
~~~~~{.cpp}
~~~~{.cpp}
typedef NCollection_Array1<gp_Vec> TColgp_Array1OfVec;
typedef NCollection_Array1<TCollection_AsciiString> TColStd_Array1OfAsciiString;
~~~~~
~~~~
Packages like *TopTools* also include definitions of collections and hash functions for complex types like shapes -- *TopTools_ShapeMapHasher*, *TopTools_MapOfShape*.
@ -1525,27 +1525,27 @@ These classes also provide a data structure to represent any expression, relatio
Vectors and matrices have arbitrary ranges which must be defined at declaration time and cannot be changed after declaration.
~~~~~{.cpp}
~~~~{.cpp}
math_Vector aVec (1, 3);
// a vector of dimension 3 with range (1..3)
math_Matrix aMat (0, 2, 0, 2);
// a matrix of dimension 3x3 with range (0..2, 0..2)
math_Vector aVec (N1, N2);
// a vector of dimension N2-N1+1 with range (N1..N2)
~~~~~
~~~~
Vector and Matrix objects use value semantics.
In other words, they cannot be shared and are copied through assignment.
~~~~~{.cpp}
~~~~{.cpp}
math_Vector aVec1 (1, 3), aVec2 (0, 2);
aVec2 = aVec1;
// aVec1 is copied into aVec2; a modification of aVec1 does not affect aVec2
~~~~~
~~~~
Vector and Matrix values may be initialized and obtained using indexes which must lie within the range definition of the vector or the matrix.
~~~~~{.cpp}
~~~~{.cpp}
math_Vector aVec (1, 3);
math_Matrix aMat (1, 3, 1, 3);
Standard_Real aValue;
@ -1554,7 +1554,7 @@ aVec (2) = 1.0;
aValue = aVec(1);
aMat (1, 3) = 1.0;
aValue = aMat (2, 2);
~~~~~
~~~~
Some operations on Vector and Matrix objects may not be legal.
In this case an exception is raised.
@ -1562,12 +1562,12 @@ Two standard exceptions are used:
* *Standard_DimensionError* exception is raised when two matrices or vectors involved in an operation are of incompatible dimensions.
* *Standard_RangeError* exception is raised if an access outside the range definition of a vector or of a matrix is attempted.
~~~~~~{.cpp}
~~~~{.cpp}
math_Vector aVec1 (1, 3), aVec2 (1, 2), aVec3 (0, 2);
aVec1 = aVec2; // error: Standard_DimensionError is raised
aVec1 = aVec3; // OK: ranges are not equal but dimensions are compatible
aVec1 (0) = 2.0; // error: Standard_RangeError is raised
~~~~~~
~~~~
@subsection occt_occt_fcug_4_3 Primitive Geometric Types
@ -1649,7 +1649,7 @@ They contain:
The example below demonstrates the use of the math_Gauss class, which implements the Gauss solution for a set of linear equations.
The following definition is an extract from the header file of the class *math_Gauss*:
~~~~~~{.cpp}
~~~~{.cpp}
class math_Gauss
{
public:
@ -1657,11 +1657,11 @@ public:
Standard_Boolean IsDone() const;
void Solve (const math_Vector& B, math_Vector& X) const;
};
~~~~~~
~~~~
Now the main program uses the math_Gauss class to solve the equations _a*x1=b1_ and _a*x2=b2_:
~~~~~{.cpp}
~~~~{.cpp}
#include <math_Vector.hxx>
#include <math_Matrix.hxx>
main()
@ -1686,12 +1686,12 @@ main()
// StdFail_NotDone is raised
}
}
~~~~~
~~~~
The next example demonstrates the use of the *math_BissecNewton* class, which implements a combination of the Newton and Bissection algorithms to find the root of a function known to lie between two bounds.
The definition is an extract from the header file of the class *math_BissecNewton*:
~~~~~{.cpp}
~~~~{.cpp}
class math_BissecNewton
{
public:
@ -1702,12 +1702,12 @@ public:
Standard_Boolean IsDone() const;
Standard_Real Root();
};
~~~~~
~~~~
The abstract class *math_FunctionWithDerivative* describes the services which have to be implemented for the function _f_ which is to be used by a *math_BissecNewton* algorithm.
The following definition corresponds to the header file of the abstract class *math_FunctionWithDerivative*:
~~~~~{.cpp}
~~~~{.cpp}
class math_FunctionWithDerivative
{
public:
@ -1715,12 +1715,12 @@ public:
virtual Standard_Boolean Derivative (const Standard_Real x, Standard_Real& d) = 0;
virtual Standard_Boolean Values (const Standard_Real x, Standard_Real& f, Standard_Real& d) = 0;
};
~~~~~
~~~~
Now the test sample uses the *math_BissecNewton* class to find the root of the equation _f(x)=x**2-4_ in the interval [1.5, 2.5].
The function to solve is implemented in the class *myFunction* which inherits from the class *math_FunctionWithDerivative*, then the main program finds the required root.
~~~~~{.cpp}
~~~~{.cpp}
#include <math_BissecNewton.hxx>
#include <math_FunctionWithDerivative.hxx>
class myFunction : public math_FunctionWithDerivative
@ -1759,7 +1759,7 @@ main()
else // no
{
}
~~~~~
~~~~
@subsection occt_occt_fcug_4_7 Precision
@ -1796,10 +1796,10 @@ The choice of precision value for parametric space depends not only on the accur
This is because it is desirable to link parametric precision and real precision.
If you are on a curve defined by the equation *P(t)*, you would want to have equivalence between the following:
~~~~~
~~~~{.cpp}
Abs (t1 - t2) < ParametricPrecision
Distance (P(t1), P(t2)) < RealPrecision
~~~~~
~~~~
@subsubsection occt_occt_fcug_4_7_1 The Precision package
@ -1832,7 +1832,7 @@ This method is used to compare two angles.
Its current value is *Epsilon(2 * PI)* i.e. the smallest number *x* such that *2*PI + x* is different of *2\*PI*.
It can be used to check confusion of two angles as follows:
~~~{.cpp}
~~~~{.cpp}
bool areEqualAngles (double theAngle1, double theAngle2)
{
return Abs(theAngle1 - theAngle2) < Precision::Angular();
@ -1840,7 +1840,7 @@ bool areEqualAngles (double theAngle1, double theAngle2)
~~~
It is also possible to check parallelism of two vectors as follows:
~~~{.cpp}
~~~~{.cpp}
bool areParallelVectors (const gp_Vec& theVec1, const gp_Vec& theVec2)
{
return theVec1.IsParallel (theVec2, Precision::Angular());
@ -1849,7 +1849,7 @@ bool areParallelVectors (const gp_Vec& theVec1, const gp_Vec& theVec2)
Note that *Precision::Angular()* can be used on both dot and cross products because for small angles the *Sine* and the *Angle* are equivalent.
So to test if two directions of type *gp_Dir* are perpendicular, it is legal to use the following code:
~~~{.cpp}
~~~~{.cpp}
bool arePerpendicular (const gp_Dir& theDir1, const gp_Dir& theDir2)
{
return Abs(theDir1 * theDir2) < Precision::Angular();
@ -1862,7 +1862,7 @@ This method is used to test 3D distances.
The current value is *1.e-7*, in other words, 1/10 micron if the unit used is the millimeter.
It can be used to check confusion of two points as follows:
~~~{.cpp}
~~~~{.cpp}
bool areEqualPoints (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2)
{
return thePnt1.IsEqual (thePnt2, Precision::Confusion());
@ -1870,7 +1870,7 @@ bool areEqualPoints (const gp_Pnt& thePnt1, const gp_Pnt& thePnt2)
~~~
It is also possible to find a vector of null length:
~~~{.cpp}
~~~~{.cpp}
bool isNullVector (const gp_Vec& theVec)
{
return theVec.Magnitude() < Precision::Confusion();

View File

@ -60,25 +60,25 @@ Administrative data, in the Global Section of the IGES file (such as the file n
@subsection occt_iges_2_3 Description of the process
@subsubsection occt_iges_2_3_1 Loading the IGES file
Before performing any other operation, you have to load the file using the syntax below.
~~~~~
~~~~{.cpp}
IGESControl_Reader reader;
IFSelect_ReturnStatus stat = reader.ReadFile(“filename.igs”);
~~~~~
~~~~
The loading operation only loads the IGES file into computer memory; it does not translate it.
@subsubsection occt_iges_2_3_2 Checking the IGES file
This step is not obligatory. Check the loaded file with:
~~~~~
~~~~{.cpp}
Standard_Boolean ok = reader.Check(Standard_True);
~~~~~
~~~~
The variable “ok is True” is returned if no fail message was found; “ok is False” is returned if there was at least one fail message.
~~~~~
~~~~{.cpp}
reader.PrintCheckLoad (failsonly, mode);
~~~~~
~~~~
Error messages are displayed if there are invalid or incomplete IGES entities, giving you information on the cause of the error.
~~~~~
~~~~{.cpp}
Standard_Boolean failsonly = Standard_True or Standard_False;
~~~~~
~~~~
If you give True, you will see fail messages only. If you give False, you will see both fail and warning messages.
Your analysis of the file can be either message-oriented or entity-oriented. Choose your preference with *IFSelect_PrintCount mode = IFSelect_xxx*, where *xxx* can be any of the following:
@ -98,14 +98,14 @@ manages the continuity of BSpline curves (IGES entities 106, 112 and 126) after
* 2: This option concerns IGES Spline curves only. IGES Spline curves are broken down into pieces of C2 continuity. If C2 cannot be ensured, the Spline curves will be broken down into pieces of C1 continuity.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.iges.bspline.continuity");
~~~~~
~~~~
Modify this value with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetIVal ("read.iges.bspline.continuity",2))
.. error ..;
~~~~~
~~~~
Default value is 1.
This parameter does not change the continuity of curves that are used in the construction of IGES BRep entities. In this case, the parameter does not influence the continuity of the resulting OCCT curves (it is ignored).
@ -117,14 +117,14 @@ reads the precision value.
* User (1) the precision value is that of the read.precision.val parameter.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.precision.mode");
~~~~~
~~~~
Modify this value with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetIVal ("read.precision.mode",1))
.. error ..;
~~~~~
~~~~
Default value is *File* (0).
<h4>read.precision.val</h4>
@ -133,14 +133,14 @@ User defined precision value. This parameter gives the precision for shape const
This value is in the measurement unit defined in the IGES file header.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Real rp = Interface_Static::RVal("read.precision.val");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetRVal ("read.precision.val",0.001))
.. error ..;
~~~~~
~~~~
Default value is 0.0001.
The value given to this parameter is a target value that is applied to *TopoDS_Vertex, TopoDS_Edge* and *TopoDS_Face* entities. The processor does its best to reach it. Under certain circumstances, the value you give may not be attached to all of the entities concerned at the end of processing. IGES-to-OCCT translation does not improve the quality of the geometry in the original IGES file. This means that the value you enter may be impossible to attain the given quality of geometry in the IGES file.
@ -154,27 +154,27 @@ defines the mode of applying the maximum allowed tolerance. Its possible values
* *Forced(1)* maximum tolerance is used as a rigid limit, i.e. it can not be exceeded and, if this happens, tolerance is trimmed to suit the maximum-allowable value.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer mv = Interface_Static::IVal("read.maxprecision.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetIVal ("read.maxprecision.mode",1))
.. error ..;
~~~~~
~~~~
Default value is *Preferred (0)*.
<h4>read.maxprecision.val</h4>
defines the maximum allowable tolerance (in mm) of the shape. It should be not less than the basis value of tolerance set in processor (either Resolution from the file or *read.precision.val*). Actually, the maximum between *read.maxprecision.val* and basis tolerance is used to define maximum allowed tolerance.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Real rp = Interface_Static::RVal("read.maxprecision.val");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetRVal ("read.maxprecision.val",0.1))
.. error ..;
~~~~~
~~~~
Default value is 1.
<h4>read.stdsameparameter.mode</h4>
@ -183,14 +183,14 @@ defines the using of *BRepLib\::SameParameter*. Its possible values are:
* 1 (On) -- *BRepLib\::SameParameter* is called.
*BRepLib\::SameParameter* is used through *ShapeFix_Edge\::SameParameter*. It ensures that the resulting edge will have the lowest tolerance taking pcurves either unmodified from the IGES file or modified by *BRepLib\::SameParameter*.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer mv = Interface_Static::IVal("read.stdsameparameter.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetIVal ("read.stdsameparameter.mode",1))
.. error ..;
~~~~~
~~~~
Deafault value is 0 (Off).
<h4>read.surfacecurve.mode</h4>
@ -224,42 +224,42 @@ In any other case, the 2D representation is preferred to the 3D.
If either a 3D or a 2D contour is absent in the file or cannot be translated, then it is re-computed from another contour. If the translation of both 2D and 3D contours fails, the whole curve (type 141 or 142) is not translated. If this curve is used for trimming a face, the face will be translated without this trimming and will have natural restrictions.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.surfacecurve.mode");
~~~~~
~~~~
Modify this value with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetIVal ("read.surfacecurve.mode",3))
.. error ..;
~~~~~
~~~~
Default value is Default (0).
<h4>read.encoderegularity.angle</h4>
This parameter is used within the *BRepLib::EncodeRegularity()* function which is called for a shape read from an IGES or a STEP file at the end of translation process. This function sets the regularity flag of an edge in a shell when this edge is shared by two faces. This flag shows the continuity, which these two faces are connected with at that edge.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Real era = Interface_Static::RVal("read.encoderegularity.angle");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetRVal ("read.encoderegularity.angle",0.1))
.. error ..;
~~~~~
~~~~
Default value is 0.01.
<h4>read.iges.bspline.approxd1.mode</h4>
This parameter is obsolete (it is rarely used in real practice). If set to True, it affects the translation of bspline curves of degree 1 from IGES: these curves (which geometrically are polylines) are split by duplicated points, and the translator attempts to convert each of the obtained parts to a bspline of a higher continuity.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Real bam = Interface_Static::CVal("read.iges.bspline.approxd1.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetRVal ("read.encoderegularity.angle","On"))
.. error ..;
~~~~~
~~~~
Default value is Off.
@ -282,41 +282,41 @@ Default value is MM.
@subsubsection occt_iges_2_3_4 Selecting entities
A list of entities can be formed by invoking the method *IGESControl_Reader::GiveList*.
~~~~~
~~~~{.cpp}
Handle(TColStd_HSequenceOfTransient) list = reader.GiveList();
~~~~~
~~~~
Several predefined operators can be used to select a list of entities of a specific type.
To make a selection, use the method *IGESControl_Reader::GiveList* with the selection type in quotation marks as an argument. You can also make cumulative selections. For example, you would use the following syntax:
To make a selection, use the method *IGESControl_Reader::GiveList* with the selection type in quotation marks as an argument. You can also make cumulative selections. For example, you would use the following Syntax:
1. Requesting the faces in the file:
~~~~~
~~~~{.cpp}
faces = Reader.GiveList("iges-faces");
~~~~~
~~~~
2. Requesting the visible roots in the file:
~~~~~
~~~~{.cpp}
visibles = Reader.GiveList(iges-visible-roots);
~~~~~
~~~~
3. Requesting the visible faces:
~~~~~
~~~~{.cpp}
visfac = Reader.GiveList(iges-visible-roots,faces);
~~~~~
~~~~
Using a signature, you can define a selection dynamically, filtering the string by means of a criterion. When you request a selection using the method GiveList, you can give either a predefined selection or a selection by signature. You make your selection by signature using the predefined signature followed by your criterion in parentheses as shown in the example below. The syntaxes given are equivalent to each other.
~~~~~
~~~~{.cpp}
faces = Reader.GiveList(“xst-type(SurfaceOfRevolution)”);
faces = Reader.GiveList(“iges-type(120)”);
~~~~~
~~~~
You can also look for:
* values returned by your signature which match your criterion exactly
~~~~~
~~~~{.cpp}
faces = Reader.GiveList(“xst-type(=SurfaceOfRevolution)”);
~~~~~
~~~~
* values returned by your signature which do not contain your criterion
~~~~~
~~~~{.cpp}
faces = Reader.GiveList(“xst-type(!SurfaceOfRevolution)”);
~~~~~
~~~~
* values returned by your signature which do not exactly match your criterion.
~~~~~
~~~~{.cpp}
faces = Reader.GiveList(“xst-type(!=SurfaceOfRevolution)”);
~~~~~
~~~~
<h4>List of predefined operators that can be used:</h4>
* *xst-model-all* -- selects all entities.
@ -342,62 +342,62 @@ faces = Reader.GiveList(“xst-type(!=SurfaceOfRevolution)”);
@subsubsection occt_iges_2_3_5 Performing the IGES file translation
Perform translation according to what you want to translate:
1. Translate an entity identified by its rank with:
~~~~~
~~~~{.cpp}
Standard_Boolean ok = reader.Transfer (rank);
~~~~~
~~~~
2. Translate an entity identified by its handle with:
~~~~~
~~~~{.cpp}
Standard_Boolean ok = reader.TransferEntity (ent);
~~~~~
~~~~
3. Translate a list of entities in one operation with:
~~~~~
~~~~{.cpp}
Standard_Integer nbtrans = reader.TransferList (list);
reader.IsDone();
~~~~~
~~~~
where *nbtrans* returns the number of items in the list that produced a shape and *reader.IsDone()* indicates whether at least one entity was translated.
4. Translate a list of entities, entity by entity:
~~~~~
~~~~{.cpp}
Standard_Integer i,nb = list-Length();
for (i = 1; i <= nb; i ++) {
Handle(Standard_Transient) ent = list-Value(i);
Standard_Boolean OK = reader.TransferEntity (ent);
}
~~~~~
~~~~
5. Translate the whole file (all entities or only visible entities) with:
~~~~~
~~~~{.cpp}
Standard_Boolean onlyvisible = Standard_True or Standard_False;
reader.TransferRoots(onlyvisible)
~~~~~
~~~~
@subsubsection occt_iges_2_3_6 Getting the translation results
Each successful translation operation outputs one shape. A series of translations gives a series of shapes.
Each time you invoke *TransferEntity, Transfer* or *Transferlist*, their results are accumulated and NbShapes increases. You can clear the results (Clear function) between two translation operations, if you do not do this, the results from the next translation will be added to the accumulation. *TransferRoots* operations automatically clear all existing results before they start.
~~~~~
~~~~{.cpp}
Standard_Integer nbs = reader.NbShapes();
~~~~~
~~~~
returns the number of shapes recorded in the result.
~~~~~
~~~~{.cpp}
TopoDS_Shape shape = reader.Shape(num);,
~~~~~
~~~~
returns the result *num*, where *num* is an integer between 1 and *NbShapes*.
~~~~~
~~~~{.cpp}
TopoDS_Shape shape = reader.Shape();
~~~~~
~~~~
returns the first result in a translation operation.
~~~~~
~~~~{.cpp}
TopoDS_Shape shape = reader.OneShape();
~~~~~
~~~~
returns all results in a single shape which is:
* a null shape if there are no results,
* in case of a single result, a shape that is specific to that result,
* a compound that lists the results if there are several results.
~~~~~
~~~~{.cpp}
reader.Clear();
~~~~~
~~~~
erases the existing results.
~~~~~
~~~~{.cpp}
reader.PrintTransferInfo (failsonly, mode);
~~~~~
~~~~
displays the messages that appeared during the last invocation of *Transfer* or *TransferRoots*.
If *failsonly* is *IFSelect_FailOnly*, only fail messages will be output, if it is *IFSelect_FailAndWarn*, all messages will be output. Parameter “mode” can have *IFSelect_xxx* values where *xxx* can be:
@ -490,25 +490,25 @@ If a *TopoDS_Face* is output, its geometrical support is a *Geom_Surface* and i
@subsection occt_iges_2_5 Messages
Messages are displayed concerning the normal functioning of the processor (transfer, loading, etc.).
You must declare an include file:
~~~~~
~~~~{.cpp}
#include \<Interface_DT.hxx\>
~~~~~
~~~~
You have the choice of the following options for messages:
~~~~~
~~~~{.cpp}
IDT_SetLevel (level);
~~~~~
~~~~
level modifies the level of messages:
* 0: no messages
* 1: raise and fail messages are displayed, as are messages concerning file access,
* 2: warnings are also displayed.
~~~~~
~~~~{.cpp}
IDT_SetFile (“tracefile.log”);
~~~~~
~~~~
prints the messages in a file,
~~~~~
~~~~{.cpp}
IDT_SetStandard();
~~~~~
~~~~
restores screen output.
@subsection occt_iges_2_6 Tolerance management
@ -605,7 +605,7 @@ The highlighted classes produce OCCT geometry.
@subsection occt_iges_2_8 Example
~~~~~
~~~~{.cpp}
#include “IGESControl_Reader.hxx”
#include “TColStd_HSequenceOfTransient.hxx”
#include “TopoDS_Shape.hxx”
@ -627,7 +627,7 @@ cout<<"IGES Faces: "<<nIgesFaces<<" Transferred:"<<nTransFaces<<endl;
TopoDS_Shape sh = myIgesReader.OneShape();
//and obtains the results in an OCCT shape.
}
~~~~~
~~~~
@section occt_iges_3 Writing IGES
@subsection occt_iges_3_1 Procedure
@ -665,13 +665,13 @@ The following parameters are used for the OCCT-to-IGES translation.
* "Faces" (0): OCCT *TopoDS_Faces* will be translated into IGES 144 (Trimmed Surface) entities, no BRep entities will be written to the IGES file,
* "BRep" (1): OCCT *TopoDS_Faces* will be translated into IGES 510 (Face) entities, the IGES file will contain BRep entities.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer byvalue = Interface_Static::IVal("write.iges.brep.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
Interface_Static::SetIVal ("write.iges.brep.mode", 1);
~~~~~
~~~~
Default value is "Faces" (0).
* *write.convertsurface.mode* when writing to IGES in the BRep mode, this parameter indicates whether elementary surfaces (cylindrical, conical, spherical, and toroidal) are converted into corresponding IGES 5.3 entities (if the value of a parameter value is On), or written as surfaces of revolution (by default).
* *write.iges.unit:* allows choosing the unit. The default unit for Open CASCADE Technology is "MM" (millimeter). You can choose to write a file into any unit accepted by IGES.
@ -700,46 +700,46 @@ Default value is "Faces" (0).
* *write.precision.val:* is the user precision value. This parameter gives the resolution value for an IGES file when the *write.precision.mode* parameter value is 1. It is equal to 0.0001 by default, but can take any real positive (non null) value.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Real rp = Interface_Static::RVal(;write.precision.val;);
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetRVal(;write.precision.val;,0.01))
.. error ..
~~~~~
~~~~
Default value is 0.0001.
<h4>write.iges.resource.name</h4> and <h4>write.iges.sequence</h4> are the same as the corresponding read.iges.\* parameters. Note that the default sequence for writing contains *DirectFaces* operator, which converts elementary surfaces based on left-hand axes (valid in CASCADE) to right-hand axes (which are valid only in IGES).
Default values :
~~~~~
~~~~{.cpp}
write.iges.resource.name - IGES,
write.iges.sequence - ToIGES.
~~~~~
~~~~
@subsubsection occt_iges_3_3_3 Performing the Open CASCADE Technology shape translation
You can perform the translation in one or several operations. Here is how you translate topological and geometrical objects:
~~~~~
~~~~{.cpp}
Standard_Boolean ok = writer.AddShape (TopoDS_Shape);
~~~~~
~~~~
*ok* is True if translation was correctly performed and False if there was at least one entity that was not translated.
~~~~~
~~~~{.cpp}
Standard_Boolean ok = writer.AddGeom (geom);
~~~~~
~~~~
where *geom* is *Handle(Geom_Curve)* or *Handle(Geom_Surface)*;
*ok* is True if the translation was correctly performed and False if there was at least one entity whose geometry was not among the allowed types.
@subsubsection occt_iges_3_3_4 Writing the IGES file
Write the IGES file with:
~~~~~
~~~~{.cpp}
Standard_Boolean ok = writer.Write ("filename.igs");
~~~~~
~~~~
to give the file name.
~~~~~
~~~~{.cpp}
Standard_Boolean ok = writer.Write (S);
~~~~~
~~~~
where *S* is *Standard_OStream*
*ok* is True if the operation was correctly performed and False if an error occurred (for instance, if the processor could not create the file).
@ -823,7 +823,7 @@ The highlighted classes are intended to translate geometry.
@subsection occt_iges_3_7 Example
~~~~~{c++}
~~~~{.cpp}
#include <IGESControl_Controller.hxx>
#include <IGESControl_Writer.hxx>
#include <TopoDS_Shape.hxx>
@ -839,7 +839,7 @@ Standard_Integer main()
Standard_Boolean OK = ICW.Write (;MyFile.igs;);
//writes a model to the file MyFile.igs
}
~~~~~
~~~~
@section occt_iges_4 Using XSTEPDRAW
@ -852,7 +852,7 @@ In the description of commands, square brackets ([]) are used to indicate optio
A set of parameters for importing and exporting IGES files is defined in the XSTEP resource file. In XSTEPDRAW, these parameters can be viewed or changed using command
~~~~
~~~~{.php}
Draw> param [<parameter_name> [<value>]]
~~~~
@ -883,15 +883,15 @@ These parameters are set by command *param* :
It is possible either only to load an IGES file into memory (i.e. to fill the model with data from the file), or to read it (i.e. to load and convert all entities to OCCT shapes).
Loading is done by the command
~~~~~
~~~~{.php}
Draw> xload <file_name>
~~~~~
~~~~
Once the file is loaded, it is possible to investigate the structure of the loaded data. To learn how to do it see @ref occt_iges_4_4 "Analyzing the transferred".
Reading of an IGES file is done by the command
~~~~~
~~~~{.php}
Draw> igesbrep <file_name> <result_shape_name> [<selection>]
~~~~~
~~~~
Here a dot can be used instead of a filename if the file is already loaded by *xload* or *igesbrep* command. In that case, only conversion of IGES entities to OCCT shapes will be done.
Command *igesbrep* will interactively ask the user to select a set of entities to be converted:
@ -912,13 +912,13 @@ The second parameter of the *igesbrep* command defines the name of the loaded s
Instead of *igesbrep* it is possible to use commands:
~~~~~
~~~~{.php}
Draw> trimport <file_name> <result_shape_name> <selection>
~~~~~
~~~~
which outputs the result of translation of each selected entity into one shape, or
~~~~~
~~~~{.php}
Draw> trimpcomp <file_name> <result_shape_name> <selection>
~~~~~
~~~~
which outputs the result of translation of all selected entities into one shape (*TopoDS_Compound* for several entities).
An asterisk “*” can be specified instead of *selection*, it means *xst-transferrable-roots*.
@ -940,9 +940,9 @@ The procedure of analysis of the data import can be divided into two stages:
@subsubsection occt_iges_4_4_1 Checking file contents
General statistics on the loaded data can be obtained by using command
~~~~~
~~~~{.php}
Draw> data <symbol>
~~~~~
~~~~
The information printed by this command depends on the symbol specified:
| Symbol | Output |
@ -963,18 +963,18 @@ There is a set of special objects, which can be used to operate with the loaded
A list of these objects defined in the current session can be printed in DRAW by command
~~~~~
~~~~{.php}
Draw> listitems
~~~~~
~~~~
In the following commands if several <i>\<selection\></i> arguments are specified the results of each following selection are applied to the results of the previous one.
~~~~~
~~~~{.php}
Draw> givelist <selection_name> [<selection_name>]
~~~~~
~~~~
prints a list of loaded entities defined by selection argument.
~~~~~
~~~~{.php}
Draw> givecount <selection_name> [<selection_name>]
~~~~~
~~~~
prints a number of loaded entities defined by <i>selection</i> argument.
Three commands are used to calculate statistics on the entities in the model:
@ -991,9 +991,9 @@ Optional <i>\<selection\></i> argument, if specified, defines a subset of entiti
| iges-levels | Calculates how much entities lie in different IGES levels |
The command:
~~~~~
~~~~{.php}
Draw> listtypes <selection_name> ...
~~~~~
~~~~
gives a list of entity types which were encountered in the last loaded file (with a number of IGES entities of each type). The list can be shown not for all entities but for a subset of them. This subset is defined by an optional selection argument.
Entities in the IGES file are numbered in the succeeding order. An entity can be identified either by its number (#) or by its label. Label is the letter D followed by the index of the first line with the data for this entity in the Directory Entry section of the IGES file. The label can be calculated on the basis of the number as D(2*# -1). For example, entity # 6 has label D11.
@ -1006,9 +1006,9 @@ Entities in the IGES file are numbered in the succeeding order. An entity can b
@subsubsection occt_iges_4_4_2 Estimating the results of reading IGES
All of the following commands are available only after the data are converted into OCCT shapes (i.e. after command **igesbrep**).
~~~~~
~~~~{.php}
Draw> tpstat [*|?]<symbol> [<selection>]
~~~~~
~~~~
provides all statistics on the last transfer, including the list of transferred entities with mapping from IGES to OCCT types, as well as fail and warning messages. The parameter <i>\<symbol\></i> defines what information will be printed:
* G -- General statistics (list of results and messages)
* C -- Count of all warning and fail messages
@ -1028,13 +1028,13 @@ Optional argument <i>\<selection\></i> can limit the action of the command with
To get help, run this command without arguments.
For example, to get translation ratio on IGES faces, you can use.
~~~~~
~~~~{.php}
Draw:> tpstat *l iges-faces
~~~~~
~~~~
The second version of the same command is TPSTAT (not capital spelling).
~~~~~
~~~~{.php}
Draw:> TPSTAT <symbol>
~~~~~
~~~~
Symbol can be of the following values:
* g -- General statistics (list of results and messages)
* c -- Count of all warning and fail messages
@ -1045,37 +1045,37 @@ Symbol can be of the following values:
Sometimes the trimming contours of IGES faces (i.e., entity 141 for 143, 142 for 144) can be lost during translation due to fails.
The number of lost trims and the corresponding IGES entities can be obtained by the command:
~~~~~
~~~~{.php}
Draw> tplosttrim [<IGES_type>]
~~~~~
~~~~
It outputs the rank and DE numbers of faces that lost their trims and their numbers for each type (143, 144, 510) and their total number. If a face lost several of its trims it is output only once.
Optional parameter <i>\<IGES_type\></i> can be *TrimmedSurface, BoundedSurface* or *Face* to specify the only type of IGES faces.
For example, to get untrimmed 144 entities, use command
~~~~~
~~~~{.php}
Draw> tplosttrim TrimmedSurface
~~~~~
~~~~
To get the information on OCCT shape contents, use command
~~~~~
~~~~{.php}
Draw> statshape <shape_name>
~~~~~
~~~~
It outputs the number of each kind of shapes (vertex, edge, wire, etc.) in a shape and some geometrical data (number of C0 surfaces, curves, indirect surfaces, etc.).
Note. The number of faces is returned as a number of references. To obtain the number of single instances the standard command (from TTOPOLOGY executable) **nbshapes** can be used.
To analyze the internal validity of a shape, use command
~~~~~
~~~~{.php}
Draw> checkbrep <shape_name> <expurged_shape_name>
~~~~~
~~~~
It checks the geometry and topology of a shape for different cases of inconsistency, like self-intersecting wires or wrong orientation of trimming contours. If an error is found, it copies bad parts of the shape with the names "expurged_subshape_name _#" and generates an appropriate message. If possible, this command also tries to find IGES entities the OCCT shape was produced from.
<i>\<expurged_shape_name\></i> will contain the original shape without invalid subshapes.
To get information on tolerances of subshapes, use command
~~~~~
~~~~{.php}
Draw> tolerance <shape_name> [<min> [<max>] [<symbol>]]
~~~~~
~~~~
It outputs maximum, average and minimum values of tolerances for each kind of subshapes having tolerances or it can output tolerances of all subshapes of the whole shape.
When specifying *min* and *max* arguments this command outputs shapes with names <i>\<shape_name\>...</i> and their total number with tolerances in the range <i>[min, max]</i>.
@ -1099,19 +1099,19 @@ Refer to @ref occt_iges_3_3_2 "Setting the translation parameters" for a descrip
| Measurement units | XSTEP.iges.unit | 1-11 (or a string value) |
Several shapes can be written in one file. To start writing a new file, enter command
~~~~~
~~~~{.php}
Draw> newmodel
~~~~~
~~~~
This command clears the *InterfaceModel* to make it empty.
~~~~~
~~~~{.php}
Draw> brepiges <shape_name_1> [<filename.igs>]
~~~~~
~~~~
Converts the specified shapes into IGES entities and puts them into the *InterfaceModel*.
~~~~~
~~~~{.php}
Draw> writeall <filename.igs>
~~~~~
~~~~
Allows writing the prepared model to a file with name *filename.igs*.
@section occt_iges_5 Reading from and writing to IGES
@ -1121,10 +1121,10 @@ Allows writing the prepared model to a file with name *filename.igs*.
### Load an IGES file
Before performing any other operation, you must load an IGES file with:
~~~~~
~~~~{.cpp}
IGESCAFControl_Reader reader(XSDRAW::Session(), Standard_False);
IFSelect_ReturnStatus stat = reader.ReadFile(“filename.igs”);
~~~~~
~~~~
Loading the file only memorizes, but does not translate the data.
### Check the loaded IGES file
@ -1137,64 +1137,64 @@ See the description of @ref occt_iges_2_3_3 "Setting translation parameters" abo
In addition, the following parameters can be set for XDE translation of attributes:
* For transferring colors:
~~~~~
~~~~{.cpp}
reader.SetColorMode(mode);
// mode can be Standard_True or Standard_False
~~~~~
~~~~
* For transferring names:
~~~~~
~~~~{.cpp}
reader.SetNameMode(mode);
// mode can be Standard_True or Standard_False
~~~~~
~~~~
### Translate an IGES file to XDE
The following function performs a translation of the whole document:
~~~~~
~~~~{.cpp}
Standard_Boolean ok = reader.Transfer(doc);
~~~~~
~~~~
where *doc* is a variable which contains a handle to the output document and should have a type *Handle(TDocStd_Document)*.
@subsection occt_iges_5_2 Writing to IGES
The translation from XDE to IGES can be initialized as follows:
~~~~~
~~~~{.cpp}
IGESCAFControl_Writer aWriter(XSDRAW::Session(),Standard_False);
~~~~~
~~~~
### Set parameters for translation from XDE to IGES
The following parameters can be set for translation of attributes to IGES:
* For transferring colors:
~~~~~
~~~~{.cpp}
aWriter.SetColorMode(mode);
// mode can be Standard_True or Standard_False
~~~~~
~~~~
* For transferring names:
~~~~~
~~~~{.cpp}
aWriter.SetNameMode(mode);
// mode can be Standard_True or Standard_False
~~~~~
~~~~
### Translate an XDE document to IGES
You can perform the translation of a document by calling the function:
~~~~~
~~~~{.cpp}
IFSelect_ReturnStatus aRetSt = aWriter.Transfer(doc);
~~~~~
~~~~
where "doc" is a variable which contains a handle to the input document for transferring and should have a type *Handle(TDocStd_Document)*.
### Write an IGES file
Write an IGES file with:
~~~~~
~~~~{.cpp}
IFSelect_ReturnStatus statw = aWriter.WriteFile("filename.igs");
~~~~~
~~~~
or
~~~~~
~~~~{.cpp}
IFSelect_ReturnStatus statw = writer.WriteFile (S);
~~~~~
~~~~
where S is OStream.

View File

@ -479,10 +479,10 @@ See more detailed description of the @ref occt_draw_13_1 "tinspector" command.
The simple code to start Inspector with all plugins loaded:
~~~~~
~~~~
pload INSPECTOR
tinspector
~~~~~
~~~~
@figure{drawexe_tinspector.png,"tinspector",360}
@ -509,7 +509,7 @@ In general, the following steps should be taken:
Here is an example of C++ implementation:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
#include <inspector/TInspector_Communicator.hxx>
@ -533,7 +533,7 @@ void CreateInspector()
}
MyTCommunicator->SetVisible (true);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Give one the following objects for a plugin using a container of parameters:

View File

@ -30,7 +30,7 @@ Learn more about SALOME platform on https://www.salome-platform.org
The algorithm of shape triangulation is provided by the functionality of *BRepMesh_IncrementalMesh* class, which adds a triangulation of the shape to its topological data structure. This triangulation is used to visualize the shape in shaded mode.
~~~~~
~~~~{.cpp}
#include <IMeshData_Status.hxx>
#include <IMeshTools_Parameters.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
@ -69,7 +69,7 @@ Standard_Boolean meshing_imeshtools_parameters()
const Standard_Integer aStatus = aMesher.GetStatusFlags();
return !aStatus;
}
~~~~~
~~~~
The default meshing algorithm *BRepMesh_IncrementalMesh* has two major options to define triangulation -- linear and angular deflections.
@ -194,7 +194,7 @@ OCCT comes with two base 2D meshing algorithms: *BRepMesh_MeshAlgoFactory* (used
The following example demonstrates how it could be done from *Draw* environment:
~~~~~
~~~~{.php}
psphere s 10
### Default Algo ###
@ -202,11 +202,11 @@ incmesh s 0.0001 -algo default
### Delabella Algo ###
incmesh s 0.0001 -algo delabella
~~~~~
~~~~
The code snippet below shows passing a custom mesh factory to BRepMesh_IncrementalMesh:
~~~~~
~~~~{.cpp}
IMeshTools_Parameters aMeshParams;
Handle(IMeshTools_Context) aContext = new BRepMesh_Context();
aContext->SetFaceDiscret (new BRepMesh_FaceDiscret (new BRepMesh_DelabellaMeshAlgoFactory()));
@ -216,7 +216,7 @@ aMesher.SetShape (aShape);
aMesher.ChangeParameters() = aMeshParams;
aMesher.Perform (aContext);
~~~~~
~~~~
#### Range splitter
Range splitter tools provide functionality to generate internal surface nodes defined within the range computed using discrete model data. The base functionality is provided by *BRepMesh_DefaultRangeSplitter* which can be used without modifications in case of planar surface. The default splitter does not generate any internal node.

File diff suppressed because it is too large Load Diff

View File

@ -52,14 +52,14 @@ The class *Interpolate* from *GeomAPI* package allows building a constrained 3D
@figure{/user_guides/modeling_data/images/modeling_data_image003.png,"Approximation of a BSpline from scattered points",420}
This class may be instantiated as follows:
~~~~~
~~~~{.cpp}
GeomAPI_Interpolate Interp(Points);
~~~~~
~~~~
From this object, the BSpline curve may be requested as follows:
~~~~~
~~~~{.cpp}
Handle(Geom_BSplineCurve) C = Interp.Curve();
~~~~~
~~~~
#### 2D Approximation
@ -71,16 +71,16 @@ The class *PointsToBSpline* from GeomAPI package allows building a 3D BSplinecur
The resulting BSpline curve will be C2 or second degree continuous, except where a tangency constraint is defined on a point, through which the curve passes. In this case, it will be only C1 continuous. This class is instantiated as follows:
~~~~~
~~~~{.cpp}
GeomAPI_PointsToBSpline
Approx(Points,DegMin,DegMax,Continuity, Tol);
~~~~~
~~~~
From this object, the BSpline curve may be requested as follows:
~~~~~
~~~~{.cpp}
Handle(Geom_BSplineCurve) K = Approx.Curve();
~~~~~
~~~~
#### Surface Approximation
@ -184,7 +184,7 @@ The object created (or implemented) is an algorithm which can be consulted to fi
If it was unsuccessful, the status gives the reason for the failure.
~~~~
~~~~{.cpp}
gp_Pnt P1 (0.,0.,0.);
gp_Pnt P2 (0.,10.,0.);
gp_Pnt P3 (10.,0.,0.);
@ -246,7 +246,7 @@ Each class from *gp* package, such as *Circ, Circ2d, Mirror, Mirror2d*, etc., ha
It is possible to create a point using a *gce* package class, then question it to recover the corresponding *gp* object.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Pnt2d Point1,Point2;
...
//Initialization of Point1 and Point2
@ -254,13 +254,13 @@ It is possible to create a point using a *gce* package class, then question it t
if (L.Status() == gce_Done() ){
gp_Lin2d l = L.Value();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
This is useful if you are uncertain as to whether the arguments can create the *gp* object without raising an exception. In the case above, if *Point1* and *Point2* are closer than the tolerance value required by *MakeLin2d*, the function *Status* will return the enumeration *gce_ConfusedPoint*. This tells you why the *gp* object cannot be created. If you know that the points *Point1* and *Point2* are separated by the value exceeding the tolerance value, then you may create the *gp* object directly, as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
gp_Lin2d l = gce_MakeLin2d(Point1,Point2);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsubsection occt_modat_1_2_2 Geometric entities manipulated by handle
@ -363,20 +363,20 @@ The following characteristic points exist on parameterized curves in 3d space:
Let us take an adapted curve **C**, i.e. an object which is an interface between the services provided by either a 2D curve from the package Geom2d (in case of an Adaptor_Curve2d curve) or a 3D curve from the package Geom (in case of an Adaptor_Curve curve), and the services required on the curve by the computation algorithm. The adapted curve is created in the following way:
**2D case :**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Handle(Geom2d_Curve) mycurve = ... ;
Geom2dAdaptor_Curve C (mycurve) ;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
**3D case :**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
Handle(Geom_Curve) mycurve = ... ;
GeomAdaptor_Curve C (mycurve) ;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
The algorithm is then constructed with this object:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
GCPnts_UniformDeflection myAlgo () ;
Standard_Real Deflection = ... ;
myAlgo.Initialize ( C , Deflection ) ;
@ -390,7 +390,7 @@ The algorithm is then constructed with this object:
...
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsection occt_modat_1_5 Extrema
@ -771,7 +771,7 @@ There are no constructors for the classes inheriting from the *TopoDS_Shape* cla
The following example shows a routine receiving an argument of the *TopoDS_Shape* type, then putting it into a variable V if it is a vertex or calling the method ProcessEdge if it is an edge.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
@ -796,7 +796,7 @@ The following example shows a routine receiving an argument of the *TopoDS_Shape
// OK for compiler but an exception will be raised at run-time
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@ -814,7 +814,7 @@ The TopExp package provides the class *TopExp_Explorer* to find all sub-objects
The Explorer visits the whole structure in order to find the shapes of the requested type not contained in the type to avoid. The example below shows how to find all faces in the shape *S*:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
void test() {
TopoDS_Shape S;
TopExp_Explorer Ex;
@ -822,19 +822,19 @@ The Explorer visits the whole structure in order to find the shapes of the reque
ProcessFace(Ex.Current());
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Find all the vertices which are not in an edge
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
for (Ex.Init(S,TopAbs_VERTEX,TopAbs_EDGE); ...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Find all the faces in a SHELL, then all the faces not in a SHELL:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
void test() {
TopExp_Explorer Ex1, Ex2;
TopoDS_Shape S;
@ -852,14 +852,14 @@ Find all the faces in a SHELL, then all the faces not in a SHELL:
ProcessFace(Ex1.Current());
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
The Explorer presumes that objects contain only objects of an equal or inferior type. For example, if searching for faces it does not look at wires, edges, or vertices to see if they contain faces.
The *MapShapes* method from *TopExp* package allows filling a Map. An exploration using the Explorer class can visit an object more than once if it is referenced more than once. For example, an edge of a solid is generally referenced by two faces. To process objects only once, they have to be placed in a Map.
**Example**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
void TopExp::MapShapes (const TopoDS_Shape& S,
const TopAbs_ShapeEnum T,
TopTools_IndexedMapOfShape& M)
@ -870,7 +870,7 @@ The *MapShapes* method from *TopExp* package allows filling a Map. An exploratio
Ex.Next();
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
In the following example all faces and all edges of an object are drawn in accordance with the following rules:
- The faces are represented by a network of *NbIso* iso-parametric lines with *FaceIsoColor* color.
@ -886,7 +886,7 @@ The following steps are performed:
3. Exploring the edges and for each of them increment the counter of faces in the array.
4. From the Map of edges, drawing each edge with the color corresponding to the number of faces.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
void DrawShape ( const TopoDS_Shape& aShape,
const Standard_Integer nbIsos,
const Color FaceIsocolor,
@ -930,7 +930,7 @@ The following steps are performed:
}
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@subsubsection occt_modat_5_5 Lists and Maps of Shapes
@ -946,7 +946,7 @@ With a *TopTools_Map*, a set of references to Shapes can be kept without duplica
The following example counts the size of a data structure as a number of *TShapes*.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
#include <TopoDS_Iterator.hxx>
Standard_Integer Size(const TopoDS_Shape& aShape)
{
@ -959,14 +959,14 @@ The following example counts the size of a data structure as a number of *TShape
}
return size;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
This program is incorrect if there is sharing in the data structure.
Thus for a contour of four edges it should count 1 wire + 4 edges +4 vertices with the result 9, but as the vertices are each shared by two edges this program will return 13. One solution is to put all the Shapes in a Map so as to avoid counting them twice, as in the following example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
#include <TopoDS_Iterator.hxx>
#include <TopTools_MapOfShape.hxx>
@ -990,7 +990,7 @@ Thus for a contour of four edges it should count 1 wire + 4 edges +4 vertices wi
MapShapes(aShape,M);
return M.Extent();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
**Note** For more details about Maps, refer to the *TCollection* documentation (Foundation Classes Reference Manual).
@ -999,7 +999,7 @@ The following example is more ambitious and writes a program which copies a data
- A table of Shapes is created in parallel with the map to receive the copies.
- The structure is copied using the auxiliary recursive function,which copies from the map to the array.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
#include <TopoDS_Shape.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
@ -1029,7 +1029,7 @@ The following example is more ambitious and writes a program which copies a data
}
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
In the above example, the index *i* is that of the first object not treated in the Map. When *i* reaches the same size as the Map this means that everything has been treated. The treatment consists in inserting in the Map all the sub-objects, if they are not yet in the Map, they are inserted with an index greater than *i*.
@ -1037,7 +1037,7 @@ In the above example, the index *i* is that of the first object not treated in t
**Note** that the objects are inserted with a local reference set to the identity and a FORWARD orientation. Only the underlying TShape is of great interest.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
//Create an array to store the copies.
TopTools_Array1OfShapetheCopies(1,theMap.Extent());
@ -1054,12 +1054,12 @@ In the above example, the index *i* is that of the first object not treated in t
S.Location(aShape.Location());
S.Orientation(aShape.Orientation());
return S;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
Below is the auxiliary function, which copies the element of rank *i* from the map to the table. This method checks if the object has been copied; if not copied, then an empty copy is performed into the table and the copies of all the sub-elements are inserted by finding their rank in the map.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
void AuxiliaryCopy(Standard_Integer index,
const TopTools_IndexedMapOfShapes& sources,
TopTools_Array1OfShape& copies,
@ -1081,7 +1081,7 @@ Below is the auxiliary function, which copies the element of rank *i* from the m
}
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
**Wire Explorer**
@ -1093,7 +1093,7 @@ For example, in the wire in the image we want to recuperate the edges in the ord
*TopExp_Explorer*, however, recuperates the lines in any order.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Wire W = ...;
BRepTools_WireExplorer Ex;
for(Ex.Init(W); Ex.More(); Ex.Next()) {
@ -1101,7 +1101,7 @@ For example, in the wire in the image we want to recuperate the edges in the ord
ProcessTheVertexConnectingTheCurrentEdgeToThePrevious
One(Ex.CurrentVertex());
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@section occt_modat_4 Properties of Shapes

File diff suppressed because it is too large Load Diff

View File

@ -65,10 +65,10 @@ The status may contain a set of Boolean flags (internally represented by bits).
It is possible to test the status for the presence of some flag(s), using Status...() method(s) provided by the class:
~~~~~
~~~~{.cpp}
if ( object.Status.. ( ShapeExtend_DONE ) ) {// something was done
}
~~~~~
~~~~
8 'DONE' and 8 'FAIL' flags, named ShapeExtend_DONE1 ... ShapeExtend_FAIL8, are defined for a detailed analysis of the encountered situation. Each method assigns its own meaning to each flag, documented in the header for that method. There are also three enumerative values used for testing several flags at a time:
* *ShapeExtend_OK* -- if no flags have been set;
@ -131,32 +131,32 @@ The sequence of actions is as follows :
In some cases using only *ShapeFix_Shape* can be insufficient. It is possible to use tools for merging and removing small edges and fixing gaps between 2D and 3D curves.
5. Create *ShapeFix_Wireframe* tool and initialize it by shape:
~~~~~
~~~~{.cpp}
Handle(ShapeFix_Wirefarme) SFWF = new ShapeFix_Wirefarme(shape);
Or
Handle(ShapeFix_Wirefarme) SFWF = new ShapeFix_Wirefarme;
SFWF->Load(shape);
~~~~~
~~~~
6. Set the basic precision and the maximum allowed tolerance:
~~~~~
~~~~{.cpp}
sfs->SetPrecision ( Prec );
sfs->SetMaxTolerance ( maxTol );
~~~~~
~~~~
See the description for *Prec* and *maxTol* above.
7. Merge and remove small edges:
~~~~~
~~~~{.cpp}
SFWF->DropSmallEdgesMode() = Standard_True;
SFWF->FixSmallEdges();
~~~~~
~~~~
**Note:** Small edges are not removed with the default mode, but in many cases removing small edges is very useful for fixing a shape.
8. Fix gaps for 2D and 3D curves
~~~~~
~~~~{.cpp}
SFWF->FixWireGaps();
~~~~~
~~~~
9. Get the result
~~~~~
~~~~{.cpp}
TopoDS_Shape Result = SFWF->Shape();
~~~~~
~~~~
@subsection occt_shg_2_2 Shape Correction.
@ -175,7 +175,7 @@ If you want to make a fix on one sub-shape of a certain shape it is possible to
For example, in the following way it is possible to fix face *Face1* of shape *Shape1*:
~~~~~
~~~~{.cpp}
//create tools for fixing a face
Handle(ShapeFix_Face) SFF= new ShapeFix_Face;
@ -195,7 +195,7 @@ SFF->Perform();
//get the result
TopoDS_Shape NewShape = Context->Apply(Shape1);
//Resulting shape contains the fixed face.
~~~~~
~~~~
A set of required fixes and invalid sub-shapes can be obtained with the help of tools responsible for the analysis of shape validity (section 3.2).
@ -219,14 +219,14 @@ The following sequence of actions should be applied to perform fixes:
6. Get the result in two ways :
- with help of a special method *Shape(),Face(),Wire().Edge()*.
- from the rebuilding tool by method *Apply* (for access to rebuilding tool use method *Context()*):
~~~~~
~~~~{.cpp}
TopoDS_Shape resultShape = fixtool->Context()->Apply(initialShape);
~~~~~
~~~~
Modification fistory for the shape and its sub-shapes can be obtained from the tool for shape re-building (*ShapeBuild_ReShape*).
~~~~~
~~~~{.cpp}
TopoDS_Shape modifsubshape = fixtool->Context() -> Apply(initsubshape);
~~~~~
~~~~
@subsubsection occt_shg_2_3_2 Flags Management
@ -235,12 +235,12 @@ The flags *Fix...Mode()* are used to control the execution of fixing procedures
For example, it is possible to forbid performing fixes to remove small edges - *FixSmall*
~~~~~
~~~~{.cpp}
Handle(ShapeFix_Shape) Sfs = new ShapeFix_Shape(shape);
Sfs-> FixWireTool ()->FixSmallMode () =0;
if(Sfs->Perform())
TopoDS_Shape resShape = Sfs->Shape();
~~~~~
~~~~
@subsubsection occt_shg_2_3_3 Repairing tool for shapes
@ -249,7 +249,7 @@ Class *ShapeFix_Shape* allows using repairing tools for all sub-shapes of a shap
For example, it is possible to force the removal of invalid 2D curves from a face.
~~~~~
~~~~{.cpp}
TopoDS_Face face … // face with invalid 2D curves.
//creation of tool and its initialization by shape.
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape(face);
@ -271,7 +271,7 @@ cout<< "Shape could not be fixed" << endl;
else if(sfs->Status(ShapeExtent_OK)) {
cout<< "Initial face is valid with specified precision ="<< precendl;
}
~~~~~
~~~~
@subsubsection occt_shg_2_3_4 Repairing tool for solids
@ -302,7 +302,7 @@ This tool has the following control flags:
* *FixMissingSeamMode* -- mode to fix a missing seam, True by default. If True, tries to insert a seam.
* *FixSmallAreaWireMode* -- mode to fix a small-area wire, False by default. If True, drops wires bounding small areas.
~~~~~
~~~~{.cpp}
TopoDS_Face face = ...;
TopoDS_Wire wire = ...;
@ -319,7 +319,7 @@ sff.FixOrientation();
//Get the resulting face
TopoDS_Face newface = sff.Face();
~~~~~
~~~~
@subsubsection occt_shg_2_3_7 Repairing tool for wires
@ -413,7 +413,7 @@ Boolean flag *FixGapsByRanges* is used to activate an additional mode applied be
Let us create a custom set of fixes as an example.
~~~~~
~~~~{.cpp}
TopoDS_Face face = ...;
TopoDS_Wire wire = ...;
Standard_Real precision = 1e-04;
@ -437,7 +437,7 @@ Standard_Boolean LockVertex = Standard_True;
}
TopoDS_Wire newwire = sfw.Wire();
//Returns the corrected wire
~~~~~
~~~~
#### Example: Correction of a wire
@ -451,7 +451,7 @@ It is necessary to apply the @ref occt_shg_3_1_2 "tools for the analysis of wire
* there are no intersecting adjacent edges;
and then immediately apply fixing tools.
~~~~~
~~~~{.cpp}
TopoDS_Face face = ...;
TopoDS_Wire wire = ...;
Standard_Real precision = 1e-04;
@ -483,7 +483,7 @@ adjacent edges”<<endl;
// The edges are cut at the intersection point so that they no longer intersect.
}
}
~~~~~
~~~~
As the result all failures have been fixed.
@ -504,7 +504,7 @@ To see how this tool works, it is possible to take an edge, where the maximum de
First it is necessary to apply the @ref occt_shg_3_1_3 "tool for checking the edge validity" to find that the maximum deviation between pcurve and 3D curve is greater than tolerance. Then we can use the repairing tool to increase the tolerance and make the deviation acceptable.
~~~~~
~~~~{.cpp}
ShapeAnalysis_Edge sae;
TopoDS_Face face = ...;
TopoDS_Wire wire = ...;
@ -518,7 +518,7 @@ if (sae.CheckSameParameter (edge, maxdev)) {
sfe.FixSameParameter();
cout<<“New tolerance “<<BRep_Tool::Tolerance(edge)<<endl;
}
~~~~~
~~~~
@figure{/user_guides/shape_healing/images/shape_healing_image012.png,"Resulting shape",420}
@ -539,7 +539,7 @@ To perform fixes it is necessary to:
* set the working precision problems will be detected with and the maximum allowed tolerance
* perform fixes
~~~~~
~~~~{.cpp}
//creation of a tool
Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe(shape);
//sets the working precision problems will be detected with and the maximum allowed tolerance
@ -555,7 +555,7 @@ sfwf->SetLimliteAngle(angle);
sfwf->FixSmallEdges();
//getting the result
TopoDS_Shape resShape = sfwf->Shape();
~~~~~
~~~~
It is desirable that a shape is topologically correct before applying the methods of this class.
@ -567,7 +567,7 @@ Class ShapeFix_FixSmallFaceThis tool is intended for dropping small faces from t
The sequence of actions for performing the fix is the same as for the fixes described above:
~~~~~
~~~~{.cpp}
//creation of a tool
Handle(ShapeFix_FixSmallFace) sff = new ShapeFix_FixSmallFace(shape);
//setting of tolerances
@ -577,7 +577,7 @@ sff->SetMaxTolerance(maxTol);
sff.Perform();
//getting the result
TopoDS_Shape resShape = sff.FixShape();
~~~~~
~~~~
@subsubsection occt_shg_2_3_11 Tool to modify tolerances of shapes (Class ShapeFix_ShapeTolerance).
@ -589,7 +589,7 @@ You set the tolerance functionality as follows:
* set a tolerance for sub-shapes, by method SetTolerance,
* limit tolerances with given ranges, by method LimitTolerance.
~~~~~
~~~~{.cpp}
//creation of a tool
ShapeFix_ShapeTolerance Sft;
//setting a specified tolerance on shape and all of its sub-shapes.
@ -598,7 +598,7 @@ Sft.SetTolerance(shape,toler);
Sft.SetTolerance(shape,toler,TopAbs_VERTEX);
//limiting the tolerance on the shape and its sub-shapes between minimum and maximum tolerances
Sft.LimitTolerance(shape,tolermin,tolermax);
~~~~~
~~~~
@section occt_shg_3 Analysis
@ -614,7 +614,7 @@ However, if you want, these tools can be used for detecting some of shape proble
* initialize it by shape and set a tolerance problems will be detected with if it is necessary.
* check the problem that interests you.
~~~~~
~~~~{.cpp}
TopoDS_Face face = ...;
ShapeAnalysis_Edge sae;
//Creates a tool for analyzing an edge
@ -623,18 +623,18 @@ for(TopExp_Explorer Exp(face,TopAbs_EDGE);Exp.More();Exp.Next()) {
if (!sae.HasCurve3d (edge)) {
cout <<"Edge has no 3D curve"<< endl; }
}
~~~~~
~~~~
@subsubsection occt_shg_3_1_1 Analysis of orientation of wires on a face.
It is possible to check whether a face has an outer boundary with the help of method *ShapeAnalysis::IsOuterBound*.
~~~~~
~~~~{.cpp}
TopoDS_Face face … //analyzed face
if(!ShapeAnalysis::IsOuterBound(face)) {
cout<<"Face has not outer boundary"<<endl;
}
~~~~~
~~~~
@subsubsection occt_shg_3_1_2 Analysis of wire validity
@ -665,7 +665,7 @@ Some methods in this class are:
This class maintains status management. Each API method stores the status of its last execution which can be queried by the corresponding *Status..()* method. In addition, each API method returns a Boolean value, which is True when a case being analyzed is detected (with the set *ShapeExtend_DONE* status), otherwise it is False.
~~~~~
~~~~{.cpp}
TopoDS_Face face = ...;
TopoDS_Wire wire = ...;
Standard_Real precision = 1e-04;
@ -685,7 +685,7 @@ if (saw.CheckConnected()) {
if (saw.CheckSelfIntersection()) {
cout<<"Wire has self-intersecting or intersecting adjacent edges"<< endl;
}
~~~~~
~~~~
@subsubsection occt_shg_3_1_3 Analysis of edge validity
@ -699,7 +699,7 @@ Class *ShapeAnalysis_Edge* is intended to analyze edges. It provides the followi
This class supports status management described above.
~~~~~
~~~~{.cpp}
TopoDS_Face face = ...;
ShapeAnalysis_Edge sae;
//Creates a tool for analyzing an edge
@ -727,7 +727,7 @@ if(sae.CheckOverlapping(edge1,edge2,prec,dist)) {
cout<<"Edges are overlapped with tolerance = "<<prec<<endl;
cout<<"Domain of overlapping ="<<dist<<endl;
}
~~~~~
~~~~
@subsubsection occt_shg_3_1_4 Analysis of presence of small faces
@ -735,7 +735,7 @@ Class *ShapeAnalysis_CheckSmallFace* class is intended for analyzing small faces
* *CheckSpotFace()* checks if the size of the face is less than the given precision;
* *CheckStripFace* checks if the size of the face in one dimension is less than the given precision.
~~~~~
~~~~{.cpp}
TopoDS_Shape shape … // checked shape
//Creation of a tool
ShapeAnalysis_CheckSmallFace saf;
@ -750,13 +750,13 @@ NumSmallfaces++;
}
if(numSmallfaces)
cout<<"Number of small faces in the shape ="<< numSmallfaces <<endl;
~~~~~
~~~~
@subsubsection occt_shg_3_1_5 Analysis of shell validity and closure
Class *ShapeAnalysis_Shell* allows checking the orientation of edges in a manifold shell. With the help of this tool, free edges (edges entered into one face) and bad edges (edges entered into the shell twice with the same orientation) can be found. By occurrence of bad and free edges a conclusion about the shell validity and the closure of the shell can be made.
~~~~~
~~~~{.cpp}
TopoDS_Shell shell // checked shape
ShapeAnalysis_Shell sas(shell);
//analysis of the shell , second parameter is set to True for //getting free edges,(default False)
@ -770,7 +770,7 @@ if(sas.HasFreeEdges()) {
cout<<"Shell is open"<<endl;
TopoDS_Compound freeEdges = sas.FreeEdges();
}
~~~~~
~~~~
@subsection occt_shg_3_2 Analysis of shape properties.
@subsubsection occt_shg_3_2_1 Analysis of tolerance on shape
@ -783,7 +783,7 @@ The analysis of tolerance functionality is the following:
* finding sub-shapes with tolerances exceeding the given value,
* finding sub-shapes with tolerances in the given range.
~~~~~
~~~~{.cpp}
TopoDS_Shape shape = ...;
ShapeAnalysis_ShapeTolerance sast;
Standard_Real AverageOnShape = sast.Tolerance (shape, 0);
@ -796,29 +796,29 @@ Standard_Real MaxAllowed = 0.1;
if (MaxOnVertex > MaxAllowed) {
cout<<"Maximum tolerance of the vertices exceeds maximum allowed"<<endl;
}
~~~~~
~~~~
@subsubsection occt_shg_3_2_2 Analysis of free boundaries.
Class ShapeAnalysis_FreeBounds is intended to analyze and output the free bounds of a shape. Free bounds are wires consisting of edges referenced only once by only one face in the shape.
This class works on two distinct types of shapes when analyzing their free bounds:
* Analysis of possible free bounds taking the specified tolerance into account. This analysis can be applied to a compound of faces. The analyzer of the sewing algorithm (*BRepAlgo_Sewing*) is used to forecast what free bounds would be obtained after the sewing of these faces is performed. The following method should be used for this analysis:
~~~~~
~~~~{.cpp}
ShapeAnalysis_FreeBounds safb(shape,toler);
~~~~~
~~~~
* Analysis of already existing free bounds. Actual free bounds (edges shared by the only face in the shell) are output in this case. *ShapeAnalysis_Shell* is used for that.
~~~~~
~~~~{.cpp}
ShapeAnalysis_FreeBounds safb(shape);
~~~~~
~~~~
When connecting edges into wires this algorithm tries to build wires of maximum length. Two options are provided for the user to extract closed sub-contours out of closed and/or open contours. Free bounds are returned as two compounds, one for closed and one for open wires. To obtain a result it is necessary to use methods:
~~~~~
~~~~{.cpp}
TopoDS_Compound ClosedWires = safb.GetClosedWires();
TopoDS_Compound OpenWires = safb.GetOpenWires();
~~~~~
~~~~
This class also provides some static methods for advanced use: connecting edges/wires to wires, extracting closed sub-wires from wires, distributing wires into compounds for closed and open wires.
~~~~~
~~~~{.cpp}
TopoDS_Shape shape = ...;
Standard_Real SewTolerance = 1.e-03;
//Tolerance for sewing
@ -834,7 +834,7 @@ TopoDS_Compound ClosedWires = safb.GetClosedWires();
//Returns a compound of closed free bounds
TopoDS_Compound OpenWires = safb.GetClosedWires();
//Returns a compound of open free bounds
~~~~~
~~~~
@subsubsection occt_shg_3_2_3 Analysis of shape contents
@ -866,7 +866,7 @@ The corresponding flags should be set to True for storing a shape by a specified
Let us, for example, select faces based on offset surfaces.
~~~~~
~~~~{.cpp}
ShapeAnalysis_ShapeContents safc;
//set a corresponding flag for storing faces based on the offset surfaces
safc.ModifyOffsetSurfaceMode() = Standard_True;
@ -875,7 +875,7 @@ safc.Perform(shape);
Standard_Integer NbOffsetSurfaces = safc.NbOffsetSurf();
//getting the sequence of faces based on offset surfaces.
Handle(TopTools_HSequenceOfShape) seqFaces = safc.OffsetSurfaceSec();
~~~~~
~~~~
@section occt_shg_4 Upgrading
@ -918,7 +918,7 @@ The usual way to use these tools exception for the tool of converting a C0 BSpli
Let us, for example, split all surfaces and all 3D and 2D curves having a continuity of less the C2.
~~~~~
~~~~{.cpp}
//create a tool and initializes it by shape.
ShapeUpgrade_ShapeDivideContinuity ShapeDivedeCont(initShape);
@ -942,7 +942,7 @@ if(ShapeDivideCont.Status(ShapeExtend_DONE)
for(TopExp_Explorer aExp(initShape,TopAbs_FACE); aExp.More(0; aExp.Next()) {
TopoDS_Shape modifShape = ShapeDivideCont.GetContext()-> Apply(aExp.Current());
}
~~~~~
~~~~
@subsubsection occt_shg_4_1_3 Creation of a new tool for splitting a shape.
To create a new splitting tool it is necessary to create tools for geometry splitting according to a desirable criterion. The new tools should be inherited from basic tools for geometry splitting. Then the new tools should be set into corresponding tools for shape splitting.
@ -953,7 +953,7 @@ To change the value of criterion of shape splitting it is necessary to create a
Let us split a shape according to a specified criterion.
~~~~~
~~~~{.cpp}
//creation of new tools for geometry splitting by a specified criterion.
Handle(MyTools_SplitSurfaceTool) MySplitSurfaceTool = new MyTools_SplitSurfaceTool;
Handle(MyTools_SplitCurve3DTool) MySplitCurve3Dtool = new MyTools_SplitCurve3DTool;
@ -987,7 +987,7 @@ TopoDS_Shape splitShape = ShapeDivide.GetResult();
for(TopExp_Explorer aExp(initShape,TopAbs_FACE); aExp.More(0; aExp.Next()) {
TopoDS_Shape modifShape = ShapeDivide.GetContext()-> Apply(aExp.Current());
}
~~~~~
~~~~
@subsection occt_shg_4_2 General splitting tools.
@ -1059,7 +1059,7 @@ To create new tools for geometry splitting it is enough to inherit a new tool fr
Header file for the tool for surface splitting by continuity:
~~~~~
~~~~{.cpp}
class ShapeUpgrade_SplitSurfaceContinuity : public ShapeUpgrade_SplitSurface {
Standard_EXPORT ShapeUpgrade_SplitSurfaceContinuity();
@ -1075,14 +1075,14 @@ GeomAbs_Shape myCriterion;
Standard_Real myTolerance;
Standard_Integer myCont;
};
~~~~~
~~~~
@subsection occt_shg_4_3 Specific splitting tools.
@subsubsection occt_shg_4_3_1 Conversion of shape geometry to the target continuity
Class *ShapeUpgrade_ShapeDivideContinuity* allows converting geometry with continuity less than the specified continuity to geometry with target continuity. If converting is not possible than geometrical object is split into several ones, which satisfy the given criteria. A topological object based on this geometry is replaced by several objects based on the new geometry.
~~~~~
~~~~{.cpp}
ShapeUpgrade_ShapeDivideContinuity sdc (shape);
sdc.SetTolerance (tol3d);
sdc.SetTolerance3d (tol2d); // if known, else 1.e-09 is taken
@ -1099,7 +1099,7 @@ if (ctx.IsRecorded (sh)) {
// if there are several results, they are recorded inside a Compound.
// .. process as needed
}
~~~~~
~~~~
@subsubsection occt_shg_4_3_2 Splitting by angle
Class *ShapeUpgrade_ShapeDivideAngle* allows splitting all surfaces of revolution, cylindrical, toroidal, conical, spherical surfaces in the given shape so that each resulting segment covers not more than the defined angle (in radians).
@ -1133,7 +1133,7 @@ This tool provides access to various flags for conversion of different types of
* *GetBSplineMode,*
Let us attempt to produce a conversion of planes to Bezier surfaces.
~~~~~
~~~~{.cpp}
//Creation and initialization of a tool.
ShapeUpgrade_ShapeConvertToBezier SCB (Shape);
//setting tolerances
@ -1144,13 +1144,13 @@ SCB.SetPlaneMode(Standard_True);
SCB.Perform();
If(SCB.Status(ShapeExtend_DONE)
TopoDS_Shape result = SCB.GetResult();
~~~~~
~~~~
@subsubsection occt_shg_4_3_4 Tool for splitting closed faces
Class *ShapeUpgrade_ShapeDivideClosed* provides splitting of closed faces in the shape to a defined number of components by the U and V parameters. It topologically and (partially) geometrically processes closed faces and performs splitting with the help of class *ShapeUpgrade_ClosedFaceDivide*.
~~~~~
~~~~{.cpp}
TopoDS_Shape aShape = …;
ShapeUpgrade_ShapeDivideClosed tool (aShape );
Standard_Real closeTol = …;
@ -1164,7 +1164,7 @@ if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) {
. . .
}
TopoDS_Shape aResult = tool.Result();
~~~~~
~~~~
@subsubsection occt_shg_4_3_5 Tool for splitting a C0 BSpline 2D or 3D curve to a sequence C1 BSpline curves
@ -1190,7 +1190,7 @@ An example of using this tool is presented in the figures below:
* To produce a splitting use method Perform from the base class.
* The result shape can be obtained with the help the method *Result()*.
~~~~~
~~~~{.cpp}
ShapeUpgrade_ShapeDivideArea tool (inputShape);
tool.MaxArea() = aMaxArea;
tool.Perform();
@ -1198,7 +1198,7 @@ if(tool.Status(ShapeExtend_DONE)) {
TopoDS_Shape ResultShape = tool.Result();
ShapeFix::SameParameter ( ResultShape, Standard_False );
}
~~~~~
~~~~
**Note** that the use of method *ShapeFix::SameParameter* is necessary, otherwise the parameter edges obtained as a result of splitting can be different.
@ -1214,27 +1214,27 @@ Customization tools are intended for adaptation of shape geometry in compliance
To implement the necessary shape modification it is enough to initialize the appropriate tool by the shape and desirable parameters and to get the resulting shape. For example for conversion of indirect surfaces in the shape do the following:
~~~~~
~~~~{.cpp}
TopoDS_Shape initialShape ..
TopoDS_Shape resultShape = ShapeCustom::DirectFaces(initialShape);
~~~~~
~~~~
@subsubsection occt_shg_4_4_1 Conversion of indirect surfaces.
~~~~~
~~~~{.cpp}
ShapeCustom::DirectFaces
static TopoDS_Shape DirectFaces(const TopoDS_Shape& S);
~~~~~
~~~~
This method provides conversion of indirect elementary surfaces (elementary surfaces with left-handed coordinate systems) in the shape into direct ones. New 2d curves (recomputed for converted surfaces) are added to the same edges being shared by both the resulting shape and the original shape *S*.
@subsubsection occt_shg_4_4_2 Shape Scaling
~~~~~
~~~~{.cpp}
ShapeCustom::ScaleShape
TopoDS_Shape ShapeCustom::ScaleShape(const TopoDS_Shape& S,
const Standard_Real scale);
~~~~~
~~~~
This method returns a new shape, which is a scaled original shape with a coefficient equal to the specified value of scale. It uses the tool *ShapeCustom_TrsfModification*.
@ -1243,7 +1243,7 @@ This method returns a new shape, which is a scaled original shape with a coeffic
*ShapeCustom_BSplineRestriction* allows approximation of surfaces, curves and 2D curves with a specified degree, maximum number of segments, 2d tolerance and 3d tolerance. If the approximation result cannot be achieved with the specified continuity, the latter can be reduced.
The method with all parameters looks as follows:
~~~~~
~~~~{.cpp}
ShapeCustom::BsplineRestriction
TopoDS_Shape ShapeCustom::BSplineRestriction (const TopoDS_Shape& S,
const Standard_Real Tol3d, const Standard_Real Tol2d,
@ -1254,7 +1254,7 @@ ShapeCustom::BsplineRestriction
const Standard_Boolean Degree,
const Standard_Boolean Rational,
const Handle(ShapeCustom_RestrictionParameters)& aParameters)
~~~~~
~~~~
It returns a new shape with all surfaces, curves and 2D curves of BSpline/Bezier type or based on them, converted with a degree less than *MaxDegree* or with a number of spans less then *NbMaxSegment* depending on the priority parameter *Degree*. If this parameter is equal to True then *Degree* will be increased to the value *GmaxDegree*, otherwise *NbMaxSegments* will be increased to the value *GmaxSegments*. *GmaxDegree* and *GMaxSegments* are the maximum possible degree and the number of spans correspondingly. These values will be used in cases when an approximation with specified parameters is impossible and either *GmaxDegree* or *GMaxSegments* is selected depending on the priority.
@ -1281,22 +1281,22 @@ The following flags define whether a specified-type geometry has been converted
@subsubsection occt_shg_4_4_4 Conversion of elementary surfaces into surfaces of revolution
~~~~~
~~~~{.cpp}
ShapeCustom::ConvertToRevolution()
TopoDS_Shape ShapeCustom::ConvertToRevolution(const TopoDS_Shape& S) ;
~~~~~
~~~~
This method returns a new shape with all elementary periodic surfaces converted to *Geom_SurfaceOfRevolution*. It uses the tool *ShapeCustom_ConvertToRevolution*.
@subsubsection occt_shg_4_4_5 Conversion of elementary surfaces into Bspline surfaces
~~~~~
~~~~{.cpp}
ShapeCustom::ConvertToBSpline()
TopoDS_Shape ShapeCustom::ConvertToBSpline( const TopoDS_Shape& S,
const Standard_Boolean extrMode,
const Standard_Boolean revolMode,
const Standard_Boolean offsetMode);
~~~~~
~~~~
This method returns a new shape with all surfaces of linear extrusion, revolution and offset surfaces converted according to flags to *Geom_BSplineSurface* (with the same parameterization). It uses the tool *ShapeCustom_ConvertToBSpline*.
@ -1308,13 +1308,13 @@ If, in addition to the resulting shape, you want to get the history of modificat
The general calling syntax for scaling is
~~~~~
~~~~{.cpp}
TopoDS_Shape scaled_shape = ShapeCustom::ScaleShape(shape, scale);
~~~~~
~~~~
Note that scale is a real value. You can refine your mapping process by using additional calls to follow shape mapping sub-shape by sub-shape. The following code along with pertinent includes can be used:
~~~~~
~~~~{.cpp}
p_Trsf T;
Standard_Real scale = 100; // for example!
T.SetScale (gp_Pnt (0, 0, 0), scale);
@ -1324,13 +1324,13 @@ TopTools_DataMapOfShapeShape context;
BRepTools_Modifier MD;
TopoDS_Shape res = ShapeCustom::ApplyModifier (
Shape, TM, context,MD );
~~~~~
~~~~
The map, called context in our example, contains the history.
Substitutions are made one by one and all shapes are transformed.
To determine what happens to a particular sub-shape, it is possible to use:
~~~~~
~~~~{.cpp}
TopoDS_Shape oneres = context.Find (oneshape);
//In case there is a doubt, you can also add:
if (context.IsBound(oneshape)) oneres = context.Find(oneshape);
@ -1342,7 +1342,7 @@ iter(context);iter(more ();iter.next ()) {
TopoDs_Shape oneshape = iter.key ();
TopoDs_Shape oneres = iter.value ();
}
~~~~~
~~~~
@subsubsection occt_shg_4_4_7 Remove internal wires
@ -1379,7 +1379,7 @@ After the processing six internal wires with contour area less than the specifie
The example of method application is also given below:
~~~~~
~~~~{.cpp}
//Initialization of the class by shape.
Handle(ShapeUpgrade_RemoveInternalWires) aTool = new ShapeUpgrade_RemoveInternalWires(inputShape);
//setting parameters
@ -1410,7 +1410,7 @@ if(aTool->Status(ShapeExtend_DONE1)) {
}
//getting result shape
TopoDS_Shape res = aTool->GetResult();
~~~~~
~~~~
@subsubsection occt_shg_4_4_8 Conversion of surfaces
@ -1427,7 +1427,7 @@ To convert surfaces to analytical form this class analyzes the form and the clos
The conversion is done only if the new (analytical) surface does not deviate from the source one more than by the given precision.
~~~~~
~~~~{.cpp}
Handle(Geom_Surface) initSurf;
ShapeCustom_Surface ConvSurf(initSurf);
//conversion to analytical form
@ -1436,7 +1436,7 @@ Handle(Geom_Surface) newSurf = ConvSurf.ConvertToAnalytical(allowedtol,Standard
Handle(Geom_Surface) newSurf = ConvSurf.ConvertToPeriodic(Standard_False);
//getting the maximum deviation of the new surface from the initial surface
Standard_Real maxdist = ConvSurf.Gap();
~~~~~
~~~~
@subsubsection occt_shg_4_4_9 Unify Same Domain
@ -1458,7 +1458,7 @@ The common methods of this tool are as follows:
* Method *Generated()* is used to get a new common shape from the old shape. If a group of edges has been unified into one common edge then method *Generated()* called on any edge from this group will return the common edge. The same goes for the faces.
The example of the usage is given below:
~~~~~
~~~~{.cpp}
// 'Sh' is the initial shape
ShapeUpgrade_UnifySameDomain USD(Sh, true, true, true); // UnifyFaces mode on, UnifyEdges mode on, ConcatBSplines mode on.
USD.Build();
@ -1467,7 +1467,7 @@ The example of the usage is given below:
//Let Sh1 as a part of Sh
//get the new (probably unified) shape form the Sh1
TopoDS_Shape ResSh1 = USD.Generated(Sh1);
~~~~~
~~~~
@section occt_shg_5_ Auxiliary tools for repairing, analysis and upgrading
@ -1490,7 +1490,7 @@ Additional method *IsNewShape* can be used to check if the shape has been record
Let us use the tool to get the result shape after modification of sub-shapes of the initial shape:
~~~~~
~~~~{.cpp}
TopoDS_Shape initialShape…
//creation of a rebuilding tool
Handle(ShapeBuild_ReShape) Context = new ShapeBuild_ReShape.
@ -1516,7 +1516,7 @@ TopoDS_Shape resultShape = Context->Apply(initialShape);
//getting the resulting sub-shape from the subshape1 of the initial shape.
TopoDS_Shape result_subshape1 = Context->Apply(subshape1);
~~~~~
~~~~
@subsection occt_shg_5_2 Status definition
@ -1546,7 +1546,7 @@ This class also provides a method to check if the edge in the wire is a seam (if
Let us remove edges from the wire and define whether it is seam edge
~~~~~
~~~~{.cpp}
TopoDS_Wire ini = ..
Handle(ShapeExtend_Wire) asewd = new ShapeExtend_Wire(initwire);
//Removing edge Edge1 from the wire.
@ -1556,7 +1556,7 @@ asewd.Remove(index_edge1);
//Definition of whether Edge2 is a seam edge
Standard_Integer index_edge2 = asewd->Index(Edge2);
asewd->IsSeam(index_edge2);
~~~~~
~~~~
@subsection occt_shg_5_4 Tool for exploring shapes
@ -1570,7 +1570,7 @@ Class *ShapeExtend_MsgRegistrator* attaches messages to objects (generic Transie
Let us send and get a message attached to object:
~~~~~
~~~~{.cpp}
Handle(ShapeExtend_MsgRegistrator) MessageReg = new ShapeExtend_MsgRegistrator;
//attaches messages to an object (shape or entity)
Message_Msg msg..
@ -1587,7 +1587,7 @@ iter.More(); iter.Next()) {
Message_Msg msg = iter.Value();
}
}
~~~~~
~~~~
@subsection occt_shg_5_6 Tools for performance measurement
@ -1595,7 +1595,7 @@ Classes *MoniTool_Timer* and *MoniTool_TimerSentry* are used for measuring the p
Let us try to use timers in *XSDRAWIGES.cxx* and *IGESBRep_Reader.cxx* to analyse the performance of command *igesbrep*:
~~~~~
~~~~{.cpp}
XSDRAWIGES.cxx
...
#include <MoniTool_Timer.hxx>
@ -1626,7 +1626,7 @@ IGESBRep_Reader.cxx
}
...
}
~~~~~
~~~~
The result of *DumpTimer()* after file translation is as follows:
@ -1646,35 +1646,35 @@ The Shape Processing functionality is implemented with the help of the *XSAlgo*
This function is used in the following way:
~~~~~
~~~~{.cpp}
TopoDS_Shape aShape = …;
Standard_Real Prec = …,
Standard_Real MaxTol = …;
TopoDS_Shape aResult;
Handle(Standard_Transient) info;
TopoDS_Shape aResult = XSAlgo::AlgoContainer()->ProcessShape(aShape, Prec, MaxTol., "Name of ResourceFile", "NameSequence", info );
~~~~~
~~~~
Let us create a custom sequence of operations:
1. Create a resource file with the name *ResourceFile*, which includes the following string:
~~~~~
~~~~{.cpp}
NameSequence.exec.op: MyOper
~~~~~
~~~~
where *MyOper* is the name of operation.
2. Input a custom parameter for this operation in the resource file, for example:
~~~~~
~~~~{.cpp}
NameSequence.MyOper.Tolerance: 0.01
~~~~~
~~~~
where *Tolerance* is the name of the parameter and 0.01 is its value.
3. Add the following string into *void ShapeProcess_OperLibrary::Init()*:
~~~~~
~~~~{.cpp}
ShapeProcess::RegisterOperator(;MyOper;,
new ShapeProcess_UOperator(myfunction));
~~~~~
~~~~
where *myfunction* is a function which implements the operation.
4. Create this function in *ShapeProcess_OperLibrary* as follows:
~~~~~
~~~~{.cpp}
static Standard_Boolean myfunction (const
Handle(ShapeProcess_Context)& context)
{
@ -1684,19 +1684,19 @@ static Standard_Boolean myfunction (const
//receive our parameter:
Standard_Real toler;
ctx->GetReal(;Tolerance;, toler);
~~~~~
~~~~
5. Make the necessary operations with *aShape* using the received value of parameter *Tolerance* from the resource file.
~~~~~
~~~~{.cpp}
return Standard_True;
}
~~~~~
~~~~
6. Define some operations (with their parameters) *MyOper1, MyOper2, MyOper3*, etc. and describe the corresponding functions in *ShapeProcess_OperLibrary*.
7. Perform the required sequence using the specified name of operations and values of parameters in the resource file.
For example: input of the following string:
~~~~~
~~~~{.cpp}
NameSequence.exec.op: MyOper1,MyOper3
~~~~~
~~~~
means that the corresponding functions from *ShapeProcess_OperLibrary* will be performed with the original shape *aShape* using parameters defined for *MyOper1* and *MyOper3* in the resource file.
It is necessary to note that these operations will be performed step by step and the result obtained after performing the first operation will be used as the initial shape for the second operation.
@ -1906,7 +1906,7 @@ All lines in the file after the key and before the next keyword (and which are n
The following example illustrates the structure of a message file:
~~~~~
~~~~{.cpp}
!This is a sample message file
!------------------------------
!Messages for ShapeAnalysis package
@ -1917,15 +1917,15 @@ Your message string goes here
!...
!
!End of the message file
~~~~~
~~~~
### Loading the message file
A custom file can be loaded into memory using the method *Message_MsgFile::LoadFile*, taking as an argument the path to your file as in the example below:
~~~~~
~~~~{.cpp}
Standard_CString MsgFilePath = ;(path)/sample.file;;
Message_MsgFile::LoadFile (MsgFilePath);
~~~~~
~~~~
@subsection occt_shg_7_3 Tool for managing filling messages
@ -1936,13 +1936,13 @@ The text of the message can contain places for parameters, which are to be fille
* integer -- coded in the text as \%d,
* real -- coded in the text as \%f.
The parameter fields are filled by the message text by calling the corresponding methods *AddInteger, AddReal* and *AddString*. Both the original text of the message and the input text with substituted parameters are stored in the object. The prepared and filled message can be output to the default trace file. The text of the message (either original or filled) can be also obtained.
~~~~~
~~~~{.cpp}
Message_Msg msg01 (;SampleKeyword;);
//Creates the message msg01, identified in the file by the keyword SampleKeyword
msg1.AddInteger (73);
msg1.AddString (;SampleFile;);
//fills out the code areas
~~~~~
~~~~
@subsection occt_shg_7_4 Tool for managing trace files
@ -1951,10 +1951,10 @@ There are two ways of using trace files:
* define an object of *Message_TraceFile*, with its own definition (file name or cout, trace level), and use it where it is defined,
* use the default trace file (file name or cout, trace level), usable from anywhere.
Use the constructor method to define the target file and the level of the messages as in the example below:
~~~~~
~~~~{.cpp}
Message_TraceFile myTF
(tracelevel, "tracefile.log", Standard_False);
~~~~~
~~~~
The parameters are as follows:
* *tracelevel* is a Standard_Integer and modifies the level of messages. It has the following values and semantics:
+ 0: gives general information such as the start and end of process;

View File

@ -119,23 +119,23 @@ For further information see 2.4 Mapping STEP entities to Open CASCADE Technology
@subsubsection occt_step_2_3_1 Loading the STEP file
Before performing any other operation you have to load the file with:
~~~~~
~~~~{.cpp}
STEPControl_Reader reader;
IFSelect_ReturnStatus stat = reader.ReadFile("filename.stp");
~~~~~
~~~~
Loading the file only memorizes the data, it does not translate it.
@subsubsection occt_step_2_3_2 Checking the STEP file
This step is not obligatory. Check the loaded file with:
~~~~~
~~~~{.cpp}
reader.PrintCheckLoad(failsonly,mode);
~~~~~
~~~~
Error messages are displayed if there are invalid or incomplete STEP entities, giving you the information on the cause of error.
If *failsonly* is true only fail messages are displayed. All messages are displayed if *failsonly* is false. Your analysis of the file can be either message-oriented or entity-oriented. Choose your preference with:
~~~~~
~~~~{.cpp}
IFSelect_PrintCount mode = IFSelect_xxx
~~~~~
~~~~
Where xxx can be one of the following:
* *ItemsByEntity* -- gives a sequential list of all messages per STEP entity,
* *CountByItem* -- gives the number of STEP entities with their types per message
@ -153,14 +153,14 @@ Defines which precision value will be used during translation (see section 2.5 b
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.precision.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("read.precision.mode",1))
.. error ..
~~~~~
~~~~
Default value is File (0).
<h4>read.precision.val:</h4>
@ -169,14 +169,14 @@ User defined precision value. This parameter gives the precision for shape const
This value is a basic value of tolerance in the processor. The value is in millimeters, independently of the length unit defined in the STEP file.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Real rp = Interface_Static::RVal("read.precision.val");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetRVal("read.precision.val",0.01))
.. error ..
~~~~~
~~~~
By default this value is 0.0001.
The value given to this parameter is a basic value for ShapeHealing algorithms and the processor. It does its best to reach it. Under certain circumstances, the value you give may not be attached to all of the entities concerned at the end of processing. STEP-to-OpenCASCADE translation does not improve the quality of the geometry in the original STEP file. This means that the value you enter may be impossible to attach to all shapes with the given quality of the geometry in the STEP file.
@ -185,14 +185,14 @@ The value given to this parameter is a basic value for ShapeHealing algorithms a
Defines the maximum allowed tolerance (in mm) of the shape. It should be not less than the basic value of tolerance set in the processor (either the uncertainty from the file or *read.precision.val*). Actually, the maximum between *read.maxprecision.val* and the basis tolerance is used to define the maximum allowed tolerance.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Real rp = Interface_Static::RVal("read.maxprecision.val");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetRVal("read.maxprecision.val",0.1))
.. error ..
~~~~~
~~~~
Default value is 1.
Note that maximum tolerance even explicitly defined by the user may be insufficient to ensure the validity of the shape (if real geometry is of bad quality). Therefore the user is provided with an additional parameter, which allows him to choose: either he prefers to ensure the shape validity or he rigidly sets the value of maximum tolerance. In the first case there is a possibility that the tolerance will not have any upper limit, in the second case the shape may be invalid.
@ -203,14 +203,14 @@ Defines the mode of applying the maximum allowed tolerance. Its possible values
* 1 (Forced) -- maximum tolerance is used as a rigid limit, i.e. no tolerance can exceed it and if it is the case, the tolerance is trimmed by the maximum tolerance.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.maxprecision.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("read.maxprecision.mode",1))
.. error ..
~~~~~
~~~~
Default value is 0 ("Preferred").
<h4>read.stdsameparameter.mode</h4>
@ -221,14 +221,14 @@ defines the use of *BRepLib::SameParameter*. Its possible values are:
The functionality of *BRepLib::SameParameter* is used through *ShapeFix_Edge::SameParameter*. It ensures that the resulting edge will have the lowest tolerance taking pcurves either unmodified from the STEP file or modified by *BRepLib::SameParameter*.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer mv = Interface_Static::IVal("read.stdsameparameter.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetIVal ("read.stdsameparameter.mode",1))
.. error ..;
~~~~~
~~~~
Default value is 0 (;Off;).
<h4>read.surfacecurve.mode:</h4>
@ -240,28 +240,28 @@ If both 2D and 3D representation of the entity are present, the computation of t
* *3DUse_Preferred (3)* : 3D curves are used to rebuild 2D ones.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer rp = Interface_Static::IVal("read.surfacecurve.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("read.surfacecurve.mode",3))
.. error ..
~~~~~
~~~~
Default value is (0).
<h4>read.encoderegularity.angle</h4>
This parameter is used for call to *BRepLib::EncodeRegularity()* function which is called for the shape read from an IGES or a STEP file at the end of translation process. This function sets the regularity flag of the edge in the shell when this edge is shared by two faces. This flag shows the continuity these two faces are connected with at that edge.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Real era = Interface_Static::RVal("read.encoderegularity.angle");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetRVal ("read.encoderegularity.angle",0.1))
.. error ..;
~~~~~
~~~~
Default value is 0.01.
<h4>step.angleunit.mode</h4>
@ -292,15 +292,15 @@ Defines the approach used for selection of top-level STEP entities for translati
* 0 (OFF) -- *SHAPE_DEFINITION_REPRESENTATION* entities are taken as top-level ones; assembly is recognized by *CONTEXT_DEPENDENT_SHAPE_REPRESENTATION* entities. This is compatibility mode, which can be used for reading legacy STEP files produced by older versions of STEP translators and having incorrect or incomplete product information.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.step.product.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("read.step.product.mode",1))
.. error ..
~~~~~
~~~~
Default value is 1 (ON).
Note that the following parameters have effect only if *read.step.product.mode* is ON.
@ -315,15 +315,15 @@ When reading AP 209 STEP files, allows selecting either only `design' or `analys
Note that in AP 203 and AP214 files all products should be marked as `design', so if this mode is set to `analysis', nothing will be read.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.step.product.context");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal(;read.step.product.context;,1))
.. error ..
~~~~~
~~~~
Default value is 1 (all).
<h4>read.step.shape.repr:</h4>
@ -340,14 +340,14 @@ Specifies preferred type of representation of the shape of the product, in case
When this option is not equal to 1, for products with multiple representations the representation having a type closest to the selected one in this list will be translated.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.step.shape.repr");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("read.step.shape.repr",1))
.. error ..
~~~~~
~~~~
Default value is 1 (All).
<h4>read.step.assembly.level:</h4>
@ -359,14 +359,14 @@ Specifies which data should be read for the products found in the STEP file:
* 4 (shape) -- Translate only shapes associated with the product, ignoring the assembly structure (if any). This can be useful to translate only a shape associated with specific product, as a complement to *assembly* mode.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.step.assembly.level");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("read.step.assembly.level",1))
.. error ..
~~~~~
~~~~
Default value is 1 (All).
@ -376,14 +376,14 @@ Defines whether shapes associated with the main *SHAPE_DEFINITION_REPRESENTATION
* 0 (OFF) -- do not translate
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.step.shape.relationship");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal(;read.step.shape.relationship;,1))
.. error ..
~~~~~
~~~~
Default value is 1 (ON).
<h4>read.step.shape.aspect:</h4>
@ -393,15 +393,15 @@ Defines whether shapes associated with the *PRODUCT_DEFINITION_SHAPE* entity of
* 0 (OFF) -- do not translate
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("read.step.shape.aspect");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal(;read.step.shape.aspect;,1))
.. error ..
~~~~~
~~~~
Default value is 1 (ON).
<h4>read.step.constructivegeom.relationship:</h4>
@ -413,9 +413,9 @@ main representation of the shape (product).
By default, the flag is set to 0 (OFF) so these entities are not translated.
Set this flag to 1 (ON) if you need to translate constructive geometry entities associated with the parts:
~~~~~
~~~~{.cpp}
if (!Interface_Static::SetIVal("read.step.constructivegeom.relationship", 1)) { .. error .. }
~~~~~
~~~~
The "CONSTRUCTIVE_GEOMETRY_REPRESENTATION" entity is translated into compound of two unlimited planar faces,
whose location is result of translation of corresponding "AXIS_PLACEMENT" entity.
@ -424,7 +424,7 @@ Note that appropriate interpretation of the translated data should be done after
The result of translation can be obtained either for the "CONSTRUCTIVE_GEOMETRY_REPRESENTATION_RELATIONSHIP" entity,
of for each of the two "AXIS2_PLACEMENT_3D" entities referenced by it. as follows:
~~~~~
~~~~{.cpp}
STEPControl_Reader aReader;
... // translate file and parse STEP model to find relevant axis entity
Handle(StepGeom_Axis2Placement3d) aSTEPAxis = ...;
@ -443,7 +443,7 @@ of for each of the two "AXIS2_PLACEMENT_3D" entities referenced by it. as follow
}
}
}
~~~~~
~~~~
@subsubsection occt_step_2_3_4 Performing the STEP file translation
@ -474,9 +474,9 @@ The following methods are used for translation:
Each successful translation operation outputs one shape. A series of translations gives a set of shapes.
Each time you invoke *TransferOne(), TransferRoot()* or *TransferList()*, their results are accumulated and the counter of results increases. You can clear the results with:
~~~~~
~~~~{.cpp}
reader.ClearShapes();
~~~~~
~~~~
between two translation operations, if you do not, the results from the next translation will be added to the accumulation.
*TransferRoots()* operations automatically clear all existing results before they start.
@ -494,9 +494,9 @@ If several individual translations follow each other, the results give a list th
<h5>Checking that translation was correctly performed</h5>
Each time you invoke *Transfer* or *TransferRoots()*, you can display the related messages with the help of:
~~~~~
~~~~{.cpp}
reader.PrintCheckTransfer(failsonly,mode);
~~~~~
~~~~
This check concerns the last invocation of *Transfer* or *TransferRoots()* only.
@ -512,35 +512,35 @@ There are three selection possibilities. You can select:
<h5>The whole file</h5>
Transferring the whole file means transferring all root entities. The number of roots can be evaluated when the file is loaded:
~~~~~
~~~~{.cpp}
Standard_Integer NbRoots = reader.NbRootsForTransfer();
Standard_Integer num = reader.TransferRoots();
~~~~~
~~~~
<h5>List of entities</h5>
A list of entities can be formed by invoking *STEP214Control_Reader::GiveList* (this is a method of the parent class).
Here is a simple example of how a list is translated:
~~~~~
~~~~{.cpp}
Handle(TColStd_HSequenceOfTransient) list = reader.GiveList();
~~~~~
~~~~
The result is a *TColStd_HSequenceOfTransient*.
You can either translate a list entity by entity or all at once. An entity-by-entity operation lets you check each individual entity translated.
<h5>Translating a whole list in one operation</h5>
~~~~~
~~~~{.cpp}
Standard_Integer nbtrans = reader.TransferList (list);
~~~~~
~~~~
*nbtrans* gives the number of items in the list that produced a shape.
<h5>Translating a list entity by entity:</h5>
~~~~~
~~~~{.cpp}
Standard_Integer i,nb = list->Length();
for (i = 1; i <= nb; i ++) {
Handle(Standard_Transient) ent = list->Value(i);
Standard_Boolean OK = reader.TransferEntity (ent);
}
~~~~~
~~~~
<h4>Selections</h4>
There is a number of predefined operators that can be used. They are:
@ -565,21 +565,21 @@ You can select an entity either by its rank or by its handle (an entity's handle
<h5>Selection by rank</h5>
Use method *StepData_StepModel::NextNumberForLabel* to find its rank with the following:
~~~~~
~~~~{.cpp}
Standard_CString label = `#...';
StepData_StepModel model = reader.StepModel();
rank = model->NextNumberForLabe(label, 0, Standard_False);
~~~~~
~~~~
Translate an entity specified by its rank:
~~~~~
~~~~{.cpp}
Standard_Boolean ok = reader.Transfer (rank);
~~~~~
~~~~
<h5>Direct selection of an entity</h5>
*ent* is the entity. The argument is a *Handle(Standard_Transient)*.
~~~~~
~~~~{.cpp}
Standard_Boolean ok = reader.TransferEntity (ent);
~~~~~
~~~~
@subsection occt_step_2_4 Mapping STEP entities to Open CASCADE Technology shapes
Tables given in this paragraph show the mapping of STEP entities to OCCT objects. Only topological and geometrical STEP entities and entities defining assembly structures are described in this paragraph. For a full list of STEP entities, refer to Appendix A.
@ -777,7 +777,7 @@ The following diagram illustrates the structure of calls in reading STEP. The hi
@figure{/user_guides/step/images/step_image003.png,"The structure of calls in reading STEP",420}
@subsection occt_step_2_7 Example
~~~~~
~~~~{.cpp}
#include <STEPControl_Reader.hxx>
#include <TopoDS_Shape.hxx>
#include <BRepTools.hxx>
@ -804,7 +804,7 @@ Standard_Integer main()
. . .
}
~~~~~
~~~~
@section occt_step_3 Writing STEP
@ -836,9 +836,9 @@ See also @ref occt_step_3_4 "Mapping OCCT shapes to STEP entities".
@subsection occt_step_3_3 Description of the process
@subsubsection occt_step_3_3_1 Initializing the process
Before performing any other operation you have to create a writer object:
~~~~~
~~~~{.cpp}
STEPControl_Writer writer;
~~~~~
~~~~
@subsubsection occt_step_3_3_2 Setting the translation parameters
The following parameters are used for the OCCT-to-STEP translation.
@ -855,10 +855,10 @@ Read this parameter with:
Standard_Integer ic = Interface_Static::IVal("write.precision.mode");
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("write.precision.mode",1))
.. error ..
~~~~~
~~~~
Default value is 0.
<h4>write.precision.val</h4>
@ -869,15 +869,15 @@ a user-defined precision value. This parameter gives the uncertainty for STEP en
This value is stored in shape_representation in a STEP file as an uncertainty.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Real rp = Interface_Static::RVal("write.precision.val");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetRVal("write.precision.val",0.01))
.. error ..
~~~~~
~~~~
Default value is 0.0001.
<h4>write.step.assembly</h4>
@ -887,14 +887,14 @@ writing assembly mode.
* 2 (Auto) : writes shapes having a structure of (possibly nested) *TopoDS_Compounds* in the form of STEP assemblies, single shapes are written without assembly structures.
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer rp = Interface_Static::IVal("write.step.assembly");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("write.step.assembly",1))
.. error ..
~~~~~
~~~~
Default value is 0.
<h4>write.step.schema</h4>
@ -906,14 +906,14 @@ defines the version of schema used for the output STEP file:
* 5 or *AP242DIS*: AP242, DIS version.
Read this parameter with:
~~~~~
~~~~{.cpp}
TCollection_AsciiString schema = Interface_Static::CVal("write.step.schema");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetCVal("write.step.schema","DIS"))
.. error ..
~~~~~
~~~~
Default value is 1 (;CD;).
For the parameter *write.step.schema* to take effect, method *STEPControl_Writer::Model(Standard_True)* should be called after changing this parameter (corresponding command in DRAW is *newmodel*).
@ -929,14 +929,14 @@ This parameter indicates whether parametric curves (curves in parametric space o
* On (1) : (default) writes pcurves to STEP file
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer wp = Interface_Static::IVal("write.surfacecurve.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("write.surfacecurve.mode",1))
.. error ..
~~~~~
~~~~
Default value is On.
<h4>write.step.unit</h4>
@ -959,14 +959,14 @@ This parameter indicates which of free vertices writing mode is switch on.
* 1 (Single Vertex) : Each vertex exported in its own SHAPE DEFINITION REPRESENTATION (vertex name and style are not lost, but size of STEP file increases).
Read this parameter with:
~~~~~
~~~~{.cpp}
Standard_Integer ic = Interface_Static::IVal("write.step.vertex.mode");
~~~~~
~~~~
Modify this parameter with:
~~~~~
~~~~{.cpp}
if(!Interface_Static::SetIVal("write.step.vertex.mode",1))
.. error ..
~~~~~
~~~~
Default value is 0.
@subsubsection occt_step_3_3_3 Performing the Open CASCADE Technology shape translation
@ -995,16 +995,16 @@ The following list shows which shapes can be translated in which mode:
If *TopoDS_Compound* contains any other types besides the ones mentioned in the table, these sub-shapes will be ignored.
In case if an OCCT shape cannot be translated according to its mode the result of translation is void.
~~~~~
~~~~{.cpp}
STEP214Control_StepModelTope mode = STEP214Control_ManifoldSolidBrep;
IFSelect_ReturnStatus stat = writer.Transfer(shape,mode);
~~~~~
~~~~
@subsubsection occt_step_3_3_4 Writing the STEP file
Write the STEP file with:
~~~~~
~~~~{.cpp}
IFSelect_ReturnStatus stat = writer.Write("filename.stp");
~~~~~
~~~~
to give the file name.
@subsection occt_step_3_4 Mapping Open CASCADE Technology shapes to STEP entities
@ -1116,7 +1116,7 @@ The highlighted classes are intended to translate geometry.
@subsection occt_step_3_7 Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
~~~~{.cpp}
#include <STEPControl.hxx>
#include <STEPControl_Writer.hxx>
#include <TopoDS_Shape.hxx>
@ -1136,7 +1136,7 @@ writer.Write(;Output.stp;);
// writes the resulting entity in the STEP file
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~
@section occt_step_4 Physical STEP file reading and writing
@ -1228,9 +1228,9 @@ In the description of commands, square brackets ([]) are used to indicate option
@subsection occt_step_6_2 Setting the interface parameters
A set of parameters for importing and exporting STEP data is defined in the XSTEP resource file. In XSDRAW, these parameters can be viewed or changed using the command
~~~~~
~~~~{.php}
Draw:> param [<parameter_name> [<value>]]
~~~~~
~~~~
Command *param* with no arguments gives a list of all parameters with their values. When the argument *parameter_name* is specified, information about this parameter is printed (current value and short description).
The third argument is used to set a new value of the given parameter. The result of the setting is printed immediately.
@ -1259,14 +1259,14 @@ For reading a STEP file, the following parameters are defined (see above, @ref o
It is possible either only to load a STEP file into memory (i.e. fill the *InterfaceModel* with data from the file), or to read it (i.e. load and convert all entities to OCCT shapes).
Loading is done by the command
~~~~~
~~~~{.php}
Draw:> xload <file_name>
~~~~~
~~~~
Once the file is loaded, it is possible to investigate the structure of the loaded data. To find out how you do it, look in the beginning of the analysis subsection.
Reading a STEP file is done by the command
~~~~~
~~~~{.php}
Draw:> stepread <file_name> <result_shape_name> [selection]
~~~~~
~~~~
Here a dot can be used instead of a filename if the file is already loaded by xload or stepread.
The optional selection (see below for a description of selections) specifies a set of entities to be translated. If an asterisk `*' is given, all transferable roots are translated. If a selection is not given, the user is prompted to define a scope of transfer interactively:
@ -1301,7 +1301,7 @@ The procedure of analysis of data import can be divided into two stages:
General statistics on the loaded data can be obtained by using the command
~~~~
~~~~{.php}
Draw:> data <symbol>
~~~~
@ -1333,10 +1333,10 @@ The command *listtypes* gives a list of entity types, which were encountered in
The list cannot be shown for all entities but for a subset of them. This subset is defined by an optional selection argument (for the list of possible values for STEP, see the table above).
Two commands are used to calculate statistics on the entities in the model:
~~~~~
~~~~{.php}
Draw:> count <counter> [<selection>]
Draw:> listcount <counter> [<selection>]
~~~~~
~~~~
The former only prints a count of entities while the latter also gives a list of them.
The optional selection argument, if specified, defines a subset of entities, which are to be taken into account. The first argument should be one of the currently defined counters:
@ -1407,9 +1407,9 @@ For writing shapes to a STEP file, the following parameters are defined (see abo
Several shapes can be written in one file. To start writing a new file, enter command *Draw:> newmodel*.
Actually, command *newmodel* will clear the *InterfaceModel* to empty it, and the next command will convert the specified shape to STEP entities and add them to the *InterfaceModel*:
~~~~~
~~~~{.php}
Draw:> stepwrite <mode> <shape_name> [<file_name>]
~~~~~
~~~~
The following modes are available :
* *a* -- "as is" -- the mode is selected automatically depending on the type & geometry of the shape;
@ -1419,10 +1419,10 @@ The following modes are available :
* *s* -- *shell_based_surface_model*
After a successful translation, if *file_name* parameter is not specified, the procedure asks you whether to write a STEP model in the file or not:
~~~~~
~~~~{.php}
execution status : 1
Mode (0 end, 1 file) :
~~~~~
~~~~
It is necessary to call command *newmodel* to perform a new translation of the next OCCT shape.
@section occt_step_7 Reading from and writing to STEP
@ -1441,10 +1441,10 @@ In addition to the translation of shapes implemented in basic translator, it pro
### Load a STEP file
Before performing any other operation, you must load a STEP file with:
~~~~~
~~~~{.cpp}
STEPCAFControl_Reader reader(XSDRAW::Session(), Standard_False);
IFSelect_ReturnStatus stat = reader.ReadFile("filename.stp");
~~~~~
~~~~
Loading the file only memorizes the data, it does not translate it.
### Check the loaded STEP file
@ -1456,22 +1456,22 @@ See a description of this step in section @ref occt_step_2_3_3 "Setting the tran
In addition, the following parameters can be set for XDE translation of attributes:
* Parameter for transferring colors:
~~~~~
~~~~{.cpp}
reader.SetColorMode(mode);
// mode can be Standard_True or Standard_False
~~~~~
~~~~
* Parameter for transferring names:
~~~~~
~~~~{.cpp}
reader.SetNameMode(mode);
// mode can be Standard_True or Standard_False
~~~~~
~~~~
### Translate a STEP file to XDE
The following function performs a translation of the whole document:
~~~~~
~~~~{.cpp}
Standard_Boolean ok = reader.Transfer(doc);
~~~~~
~~~~
where *doc* is a variable which contains a handle to the output document and should have a type *Handle(TDocStd_Document)*.
@ -1585,42 +1585,42 @@ For each Saved View OCCT STEP Reader will retrieve the following attributes:
@subsection occt_step_7_3 Writing to STEP
The translation from XDE to STEP can be initialized as follows:
~~~~~
~~~~{.cpp}
STEPCAFControl_Writer aWriter(XSDRAW::Session(),Standard_False);
~~~~~
~~~~
### Set parameters for translation from XDE to STEP
The following parameters can be set for a translation of attributes to STEP:
* For transferring colors:
~~~~~
~~~~{.cpp}
aWriter.SetColorMode(mode);
// mode can be Standard_True or Standard_False
~~~~~
~~~~
* For transferring names:
~~~~~
~~~~{.cpp}
aWriter.SetNameMode(mode);
// mode can be Standard_True or Standard_False
~~~~~
~~~~
### Translate an XDE document to STEP
You can perform the translation of document by calling the function:
~~~~~
~~~~{.cpp}
IFSelect_ReturnStatus aRetSt = aWriter.Transfer(doc);
~~~~~
~~~~
where *doc* is a variable, which contains a handle to the input document for transferring and should have a type *Handle(TDocStd_Document)*.
### Write a STEP file
Write a STEP file with:
~~~~~
~~~~{.cpp}
IFSelect_ReturnStatus statw = aWriter.WriteFile("filename.stp");
~~~~~
~~~~
or
~~~~~
~~~~{.cpp}
IFSelect_ReturnStatus statw = writer.WriteFile (S);
~~~~~
~~~~
where *S* is *OStream*.
@subsection occt_step_7_4 Attributes written to STEP
@ -1649,13 +1649,13 @@ All entities, which can be imported from STEP, can be exported too.
See the same item in section @ref occt_step_7_1 "Reading from STEP" to find more information.
Note: OCCT use AP214 by default, so for GD&T exporting AP242 should be set manually:
~~~~~
~~~~{.cpp}
Interface_Static::SetCVal("write.step.schema", "AP242DIS"));
~~~~~
~~~~
or
~~~~~
~~~~{.cpp}
Interface_Static::SetIVal("write.step.schema", 5));
~~~~~
~~~~
### Saved views
Saved Views are not exported by OCCT.

View File

@ -75,7 +75,7 @@ Additionally, *IVtkTools* package contains auxiliary methods in *IVtkTools* name
To visualize an OCCT topological shape in VTK viewer, it is necessary to perform the following steps:
1. Create *IVtkOCC_Shape* instance (VIS wrapper for OCCT shape) and initialize it with *TopoDS_Shape* object containing the actual geometry:
~~~~
~~~~{.cpp}
TopoDS_Shape aShape;
// Initialize aShape variable: e.g. load it from BREP file
@ -83,13 +83,13 @@ TopoDS_Shape aShape;
IVtkOCC_Shape::Handle aShapeImpl = new IVtkOCC_Shape(aShape);
~~~~
2. Create VTK polygonal data source for the target OCCT topological shape and initialize it with created *IVtkOCC_Shape* instance. At this stage the faceter is implicitly plugged:
~~~~
~~~~{.cpp}
vtkSmartPointer<IVtkTools_ShapeDataSource> DS = vtkSmartPointer<IVtkTools_ShapeDataSource>::New();
DS->SetShape(aShapeImpl);
~~~~
3. Visualize the loaded shape in usual VTK way starting a pipeline from the newly created specific source:
~~~~
~~~~{.cpp}
vtkSmartPointer<vtkPolyDataMapper> Mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
Mapper->SetInputConnection(aDS->GetOutputPort());
@ -99,14 +99,14 @@ Actor->SetMapper(Mapper);
~~~~
It is always possible to access the shape data source from VTK actor by means of dedicated methods from *IVtkTools_ShapeObject* class:
~~~~
~~~~{.cpp}
IVtkTools_ShapeDataSource* DS = IVtkTools_ShapeObject::GetShapeSource(Actor);
IVtkOCC_Shape::Handle occShape = IVtkTools_ShapeObject::GetOccShape(Actor);
~~~~
It is also possible to get a shape wrapper from the shape data source:
~~~~
~~~~{.cpp}
IVtkOCC_Shape::Handle occShape = DS->GetShape();
~~~~
@ -115,26 +115,26 @@ IVtkOCC_Shape::Handle occShape = DS->GetShape();
To colorize different parts of a shape according to the default OCCT color scheme, it is possible to configure the corresponding VTK mapper using a dedicated auxiliary function of *IVtkTools* namespace:
~~~~
~~~~{.cpp}
IVtkTools::InitShapeMapper(Mapper);
~~~~
It is possible to get an instance of *vtkLookupTable class* with a default OCCT color scheme by means of the following method:
~~~~
~~~~{.cpp}
vtkSmartPointer<vtkLookupTable> Table = IVtkTools::InitLookupTable();
~~~~
@subsubsection occt_vis_3_2_2 Custom color scheme
To set up application-specific colors for a shape presentation, use *InitShapeMapper* function with an additional argument passing a custom lookup table:
~~~~
~~~~{.cpp}
IVtkTools::InitShapeMapper(Mapper, Table);
~~~~
@subsubsection occt_vis_3_2_3 Setting custom colors for sub-shapes
It is also possible to bind custom colors to any sub-shape type listed in *IVtk_MeshType* enumeration. For example, to access the color bound to *free edge* entities, the following calls are available in *IVtkTools* namespace:
~~~~
~~~~{.cpp}
SetLookupTableColor(aLookupTable, MT_FreeEdge, R, G, B);
SetLookupTableColor(aLookupTable, MT_FreeEdge, R, G, B, A);
GetLookupTableColor(aLookupTable, MT_FreeEdge, R, G, B);
@ -146,7 +146,7 @@ Here *R, G, B* are double values of red, green and blue components of a color fr
As VTK color mapping approach is based on associating scalar data arrays to VTK cells, the coloring of shape components can be turned on/off in the following way:
~~~~
~~~~{.cpp}
Mapper->ScalarVisibilityOn(); // use colors from lookup table
Mapper->ScalarVisibilityOff(); // use a color of actors property
~~~~
@ -160,7 +160,7 @@ The output of the shape data source can be presented in wireframe or shading dis
For example, the shading representation can be obtained in the following way:
~~~~
~~~~{.cpp}
vtkSmartPointer<IVtkTools_ShapeDataSource> DS = vtkSmartPointer<IVtkTools_ShapeDataSource>::New();
vtkSmartPointer<IVtkTools_DisplayModeFilter> DMFilter = vtkSmartPointer<IVtkTools_DisplayModeFilter>::New();
@ -181,57 +181,57 @@ TIP: to make the shading representation smooth, use additional *vtkPolyDataNorma
@subsection occt_vis_3_4 Interactive selection
*IVtkTools* package provides *IVtkTools_ShapePicker* class to perform selection of OCCT shapes and sub-shapes in VTK viewer and access the picking results. The typical usage of *IVtkTools_ShapePicker* tool consists in the following sequence of actions:
1. Create a picker and set its renderer to your active VTK renderer:
~~~~
~~~~{.cpp}
vtkSmartPointer<IVtkTools_ShapePicker> aPicker = vtkSmartPointer<IVtkTools_ShapePicker>::New();
aPicker->SetRenderer(aRenderer);
~~~~
2. Activate the desired selection mode by choosing the corresponding sub-shape types from *IVtk_SelectionMode* enumeration. For example, the following call allows selection of edges on all selectable shape actors of the renderer:
~~~~
~~~~{.cpp}
aPicker->SetSelectionMode(SM_Edge);
~~~~
If it is necessary to limit selection by a particular shape actor, one can use the mentioned *SetSelectionMode* method with *IVtk_IShape* handle or *vtkActor* pointer as the first argument:
~~~~
~~~~{.cpp}
IVtk_IShape::Handle aShape = new IVtkOCC_Shape(occShape);
aPicker->SetSelectionMode(aShape, SM_Edge); // If shape handle is available
aPicker->SetSelectionMode(anActor, SM_Edge); // If shape actor is available
~~~~
Different selection modes can be turned on/off for a picker at the same time independently from each other.
~~~~
~~~~{.cpp}
aPicker->SetSelectionMode(SM_Edge);
aPicker->SetSelectionMode(SM_Face);
~~~~
To turn off a selection mode, the additional optional Boolean parameter is used with *false* value, for example:
~~~~
~~~~{.cpp}
aPicker->SetSelectionMode(aShape, SM_Edge, false);
~~~~
3. Call *Pick* method passing the mouse display coordinates:
~~~~
~~~~{.cpp}
aPicker->Pick(x, y, 0);
~~~~
By default, the renderer passed in the step 1 is used. In order to perform pick operation for another renderer an additional optional parameter can be specified:
~~~~
~~~~{.cpp}
aPicker->Pick(x, y, 0, aRenderer);
~~~~
4. Obtain the top-level picking results as a collection of picked VTK actors:
~~~~
~~~~{.cpp}
vtkActorCollection* anActorCollection = aPicker->GetPickedActors();
~~~~
or as a collection of picked shape IDs:
~~~~
~~~~{.cpp}
IVtk_ShapeIdList ids = aPicker->GetPickedShapesIds();
~~~~
These methods return a single top picked actor or a shape by default. To get all the picked actors or shapes it is necessary to send “true” value in the optional Boolean parameter:
~~~~
~~~~{.cpp}
anActorCollection = aPicker->GetPickedActors(true);
ids = aPicker->GetPickedShapesIds(true);
~~~~
5. Obtain the picked sub-shape IDs:
~~~~
~~~~{.cpp}
IVtk_ShapeIdList subShapeIds = aPicker->GetPickedSubShapesIds(shapeId);
~~~~
This method also returns a single ID of a top-level picked sub-shape and has the same optional Boolean parameter to get all the picked sub-shapes of a shape:
~~~~
~~~~{.cpp}
subShapeIds = aPicker->GetPickedSubShapesIds(shapeId, true);
~~~~
@ -249,7 +249,7 @@ WARNING: VIS picker essentially works on the initial topological data structures
For example, sub-shapes can be represented in VTK viewer in the following way:
~~~~
~~~~{.cpp}
// Load a shape into data source (see 3.1)
...
vtkSmartPointer<IVtkTools_ShapeDataSource> DS = vtkSmartPointer<IVtkTools_ShapeDataSource>::New();
@ -286,7 +286,7 @@ The low-level scenario of VIS usage in VTK pipeline is shown in the figure below
The visualization pipeline for OCCT shape presentation can be initialized as follows:
1. Create an instance of *IShape* class initialized by OCCT topological shape:
~~~~
~~~~{.cpp}
TopoDS_Shape aShape;
// Load or create a TopoDS_Shape in the variable a Shape
@ -294,15 +294,15 @@ TopoDS_Shape aShape;
IVtkOCC_Shape::Handle aShapeImpl = new IVtkOCC_Shape(aShape);
~~~~
2. Create an empty instance of IShapeData implementation for VTK:
~~~~
~~~~{.cpp}
IVtk_IShapeData::Handle aDataImpl = new IVtkVTK_ShapeData();
~~~~
3 Create an instance of *IShapeMesher* implementation for OCCT (any faceter can be used at this stage):
~~~~
~~~~{.cpp}
IVtk_IShapeMesher::Handle aMesher = new IVtkOCC_ShapeMesher();
~~~~
4 Triangulate the OCCT topological shape by means of the Mesher and access the result:
~~~~
~~~~{.cpp}
aMesher->Build (aShapeImpl, aDataImpl);
vtkPolyData* aPolyData = aDataImpl->GetVtkPolyData();
@ -323,17 +323,17 @@ Picking algorithm uses an instance of viewer selector (OCCT term), which manage
The typical usage of *IVtk_IShapePickerAlgo* consists in the following sequence of actions:
1. Create an instance of the picker class:
~~~~
~~~~{.cpp}
IVtkOCC_ShapePickerAlgo::Handle Picker = new IVtkOCC_ShapePickerAlgo();
~~~~
2. Set an instance of *IVtk_IView* class to the algorithm in order to define the viewer parameters:
~~~~
~~~~{.cpp}
IVtkVTK_View::Handle View = new IVtkVTK_View(Renderer);
Picker->SetView(View);
~~~~
3. Activate the desired selection modes using values from *IVtk_SelectionMode* enumeration. For example, the following call allows selection of edges:
~~~~
~~~~{.cpp}
TopoDS_Shape aShape;
// Load or create a TopoDS_Shape in the variable a Shape
...
@ -343,19 +343,19 @@ myOccPickerAlgo->SetSelectionMode(occShape, SM_Edge);
~~~~
Different selection modes can be turned on/off for a picker at the same time independently from each other.
To turn off a selection mode the additional optional Boolean parameter is used with *false* value, for example:
~~~~
~~~~{.cpp}
myOccPickerAlgo->SetSelectionMode(occShape, SM_Edge, false);
~~~~
4. Call *Pick* method passing the mouse coordinates:
~~~~
~~~~{.cpp}
myOccPickerAlgo->Pick(x, y);
~~~~
5. Obtain top-level picking results as IDs of the picked top-level shapes:
~~~~
~~~~{.cpp}
IVtk_ShapeIdList ids = myOccPickerAlgo->ShapesPicked();
~~~~
6. Obtain IDs of the picked sub-shapes:
~~~~
~~~~{.cpp}
IVtk_ShapeIdList subShapeIds
= myOccPickerAlgo->SubShapesPicked(shapeId);
~~~~

View File

@ -107,7 +107,7 @@ Additional packages, such as *Prs3d* and *Graphic3d* may be used if you need to
@subsubsection occt_visu_2_1_3 A Basic Example: How to display a 3D object
~~~~~{.cpp}
~~~~{.cpp}
Handle(V3d_Viewer) theViewer;
Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (theViewer);
@ -115,7 +115,7 @@ BRepPrimAPI_MakeWedge aWedgeMaker (theWedgeDX, theWedgeDY, theWedgeDZ, theWedgeL
TopoDS_Solid aShape = aWedgeMaker.Solid();
Handle(AIS_Shape) aShapePrs = new AIS_Shape (aShape); // creation of the presentable object
aContext->Display (aShapePrs, AIS_Shaded, 0, true); // display the presentable object and redraw 3d viewer
~~~~~
~~~~
The shape is created using the *BRepPrimAPI_MakeWedge* command.
An *AIS_Shape* is then created from the shape.
@ -450,7 +450,7 @@ After these steps, the selection manager of the created interactive context will
The code snippet below illustrates the above steps.
It also contains the code to start the detection procedure and parse the results of selection.
~~~~~{.cpp}
~~~~{.cpp}
// Suppose there is an instance of class InteractiveBox from the previous sample.
// It contains an implementation of method InteractiveBox::ComputeSelection() for selection
// modes 0 (whole box must be selected) and 1 (edge of the box must be selectable)
@ -478,7 +478,7 @@ for (theContext->InitSelected(); theContext->MoreSelected() && !aHasSelected; th
// deactivate all selection modes for aBox1
theContext->Deactivate (aBox1);
~~~~~
~~~~
It is also important to know, that there are 2 types of detection implemented for rectangular selection in OCCT:
- <b>inclusive</b> detection.
@ -489,14 +489,14 @@ It is also important to know, that there are 2 types of detection implemented fo
The standard OCCT selection mechanism uses inclusion detection by default.
To change this, use the following code:
~~~~~{.cpp}
~~~~{.cpp}
// Assume there is a created interactive context
const Handle(AIS_InteractiveContext) theContext;
// Retrieve the current viewer selector
const Handle(StdSelect_ViewerSelector3d)& aMainSelector = theContext->MainSelector();
// Set the flag to allow overlap detection
aMainSelector->AllowOverlapDetection (true);
~~~~~
~~~~
@section occt_visu_3 Application Interactive Services
@subsection occt_visu_3_1 Introduction
@ -550,18 +550,18 @@ If you are creating your own type of interactive object, you must implement the
#### For 3D:
~~~~~{.cpp}
~~~~{.cpp}
void PackageName_ClassName::Compute (const Handle(PrsMgr_PresentationManager)& thePresentationManager,
const Handle(Prs3d_Presentation)& thePresentation,
const Standard_Integer theMode);
~~~~~
~~~~
#### For hidden line removal (HLR) mode in 3D:
~~~~~{.cpp}
~~~~{.cpp}
void PackageName_ClassName::Compute (const Handle(Prs3d_Projector)& theProjector,
const Handle(Prs3d_Presentation)& thePresentation);
~~~~~
~~~~
@subsubsection occt_visu_3_2_2 Hidden Line Removal
@ -641,7 +641,7 @@ you can cancel its "infinite" status using *AIS_InteractiveObject::SetInfiniteSt
Let us take for example the class called *IShape* representing an interactive object:
~~~~~{.cpp}
~~~~{.cpp}
myPk_IShape::myPk_IShape (const TopoDS_Shape& theShape, PrsMgr_TypeOfPresentation theType)
: AIS_InteractiveObject (theType), myShape (theShape) { SetHilightMode (0); }
@ -669,7 +669,7 @@ void myPk_IShape::Compute (const Handle(Prs3d_Projector)& theProjector,
// Hidden line mode calculation algorithm
StdPrs_HLRPolyShape::Add (thePrs, myShape, myDrawer, theProjector);
}
~~~~~
~~~~
@subsubsection occt_visu_3_2_4 Selection
@ -804,14 +804,14 @@ Instances can be controlled by the following DRAW commands:
* *vlistconnected* : Lists objects in the assembly.
Have a look at the examples below:
~~~~~
~~~~{.php}
pload MODELING VISUALIZATION
vinit
psphere s 1
vdisplay s
vconnectto s2 3 0 0 s # make instance
vfit
~~~~~
~~~~
See how proxy *OpenGl_Structure* is used to represent instance:
@ -820,7 +820,7 @@ See how proxy *OpenGl_Structure* is used to represent instance:
The original object does not have to be displayed in order to make instance.
Also selection handles transformations of instances correctly:
~~~~~
~~~~{.php}
pload MODELING VISUALIZATION
vinit
psphere s 1
@ -829,13 +829,13 @@ vdisplay s # p is not displayed
vsetloc s -2 0 0
vconnect x 3 0 0 s p # make assembly
vfit
~~~~~
~~~~
@figure{/user_guides/visualization/images/visualization_image030.png,"",420}
Here is the example of a more complex hierarchy involving sub-assemblies:
~~~~~
~~~~{.php}
pload MODELING VISUALIZATION
vinit
box b 1 1 1
@ -851,7 +851,7 @@ vconnect z 2 0 0 b s
vconnect z2 4 0 0 d d2
vconnect z3 6 0 0 z z2
vfit
~~~~~
~~~~
@subsection occt_visu_3_3 Interactive Context
@ -863,20 +863,20 @@ Most functions which allow modifying the attributes of interactive objects, and
There is one essential rule to follow: the modification of an interactive object, which is already known by the Context, must be done using Context functions.
You can only directly call the functions available for an interactive object if it has not been loaded into an Interactive Context.
~~~~~{.cpp}
~~~~{.cpp}
Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
myIntContext->Display (aShapePrs, AIS_Shaded, 0, false, aShapePrs->AcceptShapeDecomposition());
myIntContext->SetColor(aShapePrs, Quantity_NOC_RED);
~~~~~
~~~~
You can also write
~~~~~{.cpp}
~~~~{.cpp}
Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
aShapePrs->SetColor (Quantity_NOC_RED);
aShapePrs->SetDisplayMode (AIS_Shaded);
myIntContext->Display (aShapePrs);
~~~~~
~~~~
@subsubsection occt_visu_3_3_2 Groups of functions
@ -903,14 +903,14 @@ When you change a graphic attribute pertaining to the Context (visualization mod
Let us examine the case of two interactive objects: *theObj1* and *theObj2*:
~~~~~{.cpp}
~~~~{.cpp}
theCtx->Display (theObj1, false);
theCtx->Display (theObj2, true); // TRUE for viewer update
theCtx->SetDisplayMode (theObj1, 3, false);
theCtx->SetDisplayMode (2, true);
// theObj2 is visualized in mode 2 (if it accepts this mode)
// theObj1 stays visualized in its mode 3
~~~~~
~~~~
*PrsMgr_PresentationManager* and *SelectMgr_ViewerSelector3d*, which manage the presentation and selection of present interactive objects, are associated to the main Viewer.
@ -965,7 +965,7 @@ There are several functions to manipulate filters:
#### Example
~~~~~{.cpp}
~~~~{.cpp}
// shading visualization mode, no specific mode, authorization for decomposition into sub-shapes
const TopoDS_Shape theShape;
Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
@ -982,7 +982,7 @@ myContext->AddFilter (aFil2);
// only faces of revolution or planar faces will be selected
myContext->MoveTo (thePixelX, thePixelY, myView, true);
~~~~~
~~~~
@subsubsection occt_visu_3_4_6 Selection
@ -996,10 +996,10 @@ There are only a few conventions and functions to be familiar with:
Highlighting of detected and selected entities is automatically managed by the Interactive Context.
The Highlight colors are those dealt with above. You can nonetheless disconnect this automatic mode if you want to manage this part yourself:
~~~~~{.cpp}
~~~~{.cpp}
AIS_InteractiveContext::SetAutomaticHilight
AIS_InteractiveContext::AutomaticHilight
~~~~~
~~~~
You can question the Interactive context by moving the mouse.
The following functions can be used:
@ -1019,7 +1019,7 @@ In case of *AIS_Shape*, the (sub)shape is returned by method *StdSelect_BRepOwne
#### Example
~~~~~{.cpp}
~~~~{.cpp}
for (myAISCtx->InitSelected(); myAISCtx->MoreSelected(); myAISCtx->NextSelected())
{
Handle(SelectMgr_EntityOwner) anOwner = myAISCtx->SelectedOwner();
@ -1030,7 +1030,7 @@ for (myAISCtx->InitSelected(); myAISCtx->MoreSelected(); myAISCtx->NextSelected(
TopoDS_Shape aShape = aBRepOwner->Shape();
}
}
~~~~~
~~~~
@subsubsection occt_visu_3_4_7 Selection schemes
@ -1101,7 +1101,7 @@ and can be built up from the source data with a custom presentation builder.
The class *AIS_ColoredShape* allows using custom colors and line widths for *TopoDS_Shape* objects and their sub-shapes.
~~~~~{.cpp}
~~~~{.cpp}
AIS_ColoredShape aColoredShape = new AIS_ColoredShape (theShape);
// setup color of entire shape
@ -1118,7 +1118,7 @@ The class *AIS_ColoredShape* allows using custom colors and line widths for *Top
// customize line width of specified sub-shape
aColoredShape->SetCustomWidth (theSubShape, 0.25);
~~~~~
~~~~
The presentation class *AIS_PointCloud* can be used for efficient drawing of large arbitrary sets of colored points.
It uses *Graphic3d_ArrayOfPoints* to pass point data into OpenGl graphic driver to draw a set points as an array of "point sprites".
@ -1130,14 +1130,14 @@ The point data is packed into vertex buffer object for performance.
@figure{point_cloud.png,"A random colored cloud of points",240}
Example:
~~~~~{.cpp}
~~~~{.cpp}
Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (2000, Standard_True);
aPoints->AddVertex (gp_Pnt(-40.0, -40.0, -40.0), Quantity_Color (Quantity_NOC_BLUE1));
aPoints->AddVertex (gp_Pnt (40.0, 40.0, 40.0), Quantity_Color (Quantity_NOC_BLUE2));
Handle(AIS_PointCloud) aPntCloud = new AIS_PointCloud();
aPntCloud->SetPoints (aPoints);
~~~~~
~~~~
The draw command *vpointcloud* builds a cloud of points from shape triangulation.
This command can also draw a sphere surface or a volume with a large amount of points (more than one million).
@ -1183,42 +1183,42 @@ You can choose between the builders to represent the object in a different way.
Moreover, you can redefine the base builder class and provide your own presentation builder.
You can add/remove builders using the following methods:
~~~~~{.cpp}
~~~~{.cpp}
MeshVS_Mesh::AddBuilder (const Handle(MeshVS_PrsBuilder)& theBuilder, Standard_Boolean theToTreatAsHilighter);
MeshVS_Mesh::RemoveBuilder (const Standard_Integer theIndex);
MeshVS_Mesh::RemoveBuilderById (const Standard_Integer theId);
~~~~~
~~~~
There is a set of reserved display and highlighting mode flags for *MeshVS_Mesh*.
Mode value is a number of bits that allows selecting additional display parameters and combining the following mode flags,
which allow displaying mesh in wireframe, shading and shrink modes:
~~~~~{.cpp}
~~~~{.cpp}
MeshVS_DMF_WireFrame
MeshVS_DMF_Shading
MeshVS_DMF_Shrink
~~~~~
~~~~
It is also possible to display deformed mesh in wireframe, shading or shrink modes using:
~~~~~{.cpp}
~~~~{.cpp}
MeshVS_DMF_DeformedPrsWireFrame
MeshVS_DMF_DeformedPrsShading
MeshVS_DMF_DeformedPrsShrink
~~~~~
~~~~
The following methods represent different kinds of data:
~~~~~{.cpp}
~~~~{.cpp}
MeshVS_DMF_VectorDataPrs
MeshVS_DMF_NodalColorDataPrs
MeshVS_DMF_ElementalColorDataPrs
MeshVS_DMF_TextDataPrs
MeshVS_DMF_EntitiesWithData
~~~~~
~~~~
The following methods provide selection and highlighting:
~~~~~{.cpp}
~~~~{.cpp}
MeshVS_DMF_SelectionPrs
MeshVS_DMF_HilightPrs
~~~~~
~~~~
*MeshVS_DMF_User* is a user-defined mode.
@ -1236,7 +1236,7 @@ There is also a set of selection modes flags that can be grouped in a combinatio
Such an object, for example, can be used for displaying the object and stored in the STL file format:
~~~~~{.cpp}
~~~~{.cpp}
// read the data and create a data source
Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFileName);
Handle(XSDRAWSTLVRML_DataSource) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh);
@ -1248,13 +1248,13 @@ aMeshPrs->SetDataSource (aDataSource);
// use default presentation builder
Handle(MeshVS_MeshPrsBuilder) aBuilder = new MeshVS_MeshPrsBuilder (aMeshPrs);
aMeshPrs->AddBuilder (aBuilder, true);
~~~~~
~~~~
*MeshVS_NodalColorPrsBuilder* allows representing a mesh with a color scaled texture mapped on it.
To do this you should define a color map for the color scale, pass this map to the presentation builder, and define an appropriate value in the range of 0.0 - 1.0 for every node.
The following example demonstrates how you can do this (check if the view has been set up to display textures):
~~~~~{.cpp}
~~~~{.cpp}
// assign nodal builder to the mesh
Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder (theMeshPrs, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask);
aBuilder->UseTexture (true);
@ -1275,7 +1275,7 @@ aBuilder->SetColorMap (aColorMap);
aBuilder->SetInvalidColor (Quantity_NOC_BLACK);
aBuilder->SetTextureCoords (aScaleMap);
aMesh->AddBuilder (aBuilder, true);
~~~~~
~~~~
@subsection occt_visu_3_6 Dynamic Selection
@ -1377,7 +1377,7 @@ You can also modify the values assigned to the vertex or query these values by t
The following example shows how to define an array of points:
~~~~~{.cpp}
~~~~{.cpp}
// create an array
Handle(Graphic3d_ArrayOfPoints) anArray = new Graphic3d_ArrayOfPoints (theVerticiesMaxCount);
@ -1389,7 +1389,7 @@ anArray->AddVertex (0.0, 10.0, 10.0);
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
aGroup->AddPrimitiveArray (anArray);
aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
~~~~~
~~~~
If the primitives share the same vertices (polygons, triangles, etc.) then you can define them as indices of the vertices array.
The method *Graphic3d_ArrayOfPrimitives::AddEdge* allows defining the primitives by indices.
@ -1398,7 +1398,7 @@ It is also possible to query the vertex defined by an edge using method *Graphic
The following example shows how to define an array of triangles:
~~~~~{.cpp}
~~~~{.cpp}
// create an array
Handle(Graphic3d_ArrayOfTriangles) anArray = new Graphic3d_ArrayOfTriangles (theVerticesMaxCount, theEdgesMaxCount, Graphic3d_ArrayFlags_None);
// add vertices to the array
@ -1415,7 +1415,7 @@ anArray->AddEdges (1, 2, 4); // second triangle
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
aGroup->AddPrimitiveArray (anArray);
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
~~~~~
~~~~
@subsubsection occt_visu_4_2_5 Text primitive
@ -1427,17 +1427,17 @@ aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
The text attributes for the group could be defined with the *Graphic3d_AspectText3d* attributes group.
To add any text to the graphic structure you can use the following methods:
~~~~~{.cpp}
~~~~{.cpp}
void Graphic3d_Group::AddText (const Handle(Graphic3d_Text)& theTextParams,
const Standard_Boolean theToEvalMinMax);
~~~~~
~~~~
You can pass FALSE as *theToEvalMinMax* if you do not want the Graphic3d structure boundaries to be affected by the text position.
**Note** that the text orientation angle can be defined by *Graphic3d_AspectText3d* attributes.
See the example:
~~~~~{.cpp}
~~~~{.cpp}
// get the group
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
@ -1452,7 +1452,7 @@ Handle(Graphic3d_Text) aText = new Graphic3d_Text (16.0f);
aText->SetText ("Text");
aText->SetPosition (gp_Pnt (1, 1, 1));
aGroup->AddText (aText);
~~~~~
~~~~
@subsubsection occt_visu_4_2_6 Materials
@ -1490,7 +1490,7 @@ OCCT visualization core supports GLSL shaders.
Custom shaders can be assigned to a generic presentation by its drawer attributes (Graphic3d aspects).
To enable custom shader for a specific AIS_Shape in your application, the following API functions can be used:
~~~~~{.cpp}
~~~~{.cpp}
// Create shader program
Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();
@ -1505,7 +1505,7 @@ aProgram->PushVariable ("MyColor", Graphic3d_Vec3 (0.0f, 1.0f, 0.0f));
// Set aspect property for specific AIS_Shape
theAISShape->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
~~~~~
~~~~
@subsection occt_visu_4_3 Graphic attributes
@ -1540,7 +1540,7 @@ This tool set contains methods for creating and editing classes of the viewer su
This sample TEST program for the *V3d* Package uses primary packages *Xw* and *Graphic3d* and secondary packages *Visual3d, Aspect, Quantity* and *math*.
~~~~~{.cpp}
~~~~{.cpp}
// create a default display connection
Handle(Aspect_DisplayConnection) aDispConnection = new Aspect_DisplayConnection();
// create a Graphic Driver
@ -1590,7 +1590,7 @@ aStruct->Display();
aView->Update();
// Fit view to object size
aView->FitAll();
~~~~~
~~~~
@subsubsection occt_visu_4_4_3 Define viewing parameters
@ -1612,12 +1612,12 @@ The camera is defined by the following properties:
Most common view manipulations (panning, zooming, rotation) are implemented as convenience methods of *V3d_View* class or by *AIS_ViewController* tool.
However *Graphic3d_Camera* class can also be used directly by application developers.
Example:
~~~~~{.cpp}
~~~~{.cpp}
// rotate camera by X axis on 30.0 degrees
gp_Trsf aTrsf;
aTrsf.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Dir (1.0, 0.0, 0.0)), M_PI / 4.0);
aView->Camera()->Transform (aTrsf);
~~~~~
~~~~
@subsubsection occt_visu_4_4_4 Orthographic Projection
@ -1625,12 +1625,12 @@ aView->Camera()->Transform (aTrsf);
The following code configures the camera for orthographic rendering:
~~~~~{.cpp}
~~~~{.cpp}
// Create an orthographic View in this Viewer
Handle(V3d_View) aView = new V3d_View (theViewer);
aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
aView->Update(); // update the Visualization in this View
~~~~~
~~~~
@subsubsection occt_visu_4_4_5 Perspective Projection
@ -1640,12 +1640,12 @@ aView->Update(); // update the Visualization in this View
The following code configures the camera for perspective rendering:
~~~~~{.cpp}
~~~~{.cpp}
// Create a perspective View in this Viewer
Handle(V3d_View) aView = new V3d_View (theViewer);
aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
aView->Update();
~~~~~
~~~~
@subsubsection occt_visu_4_4_6 Stereographic Projection
@ -1673,15 +1673,15 @@ In a non-stereo camera this effect is not visible because only the same projecti
To enable quad buffering support you should provide the following settings to the graphic driver *OpenGl_Caps*:
~~~~~{.cpp}
~~~~{.cpp}
Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver();
OpenGl_Caps& aCaps = aDriver->ChangeOptions();
aCaps.contextStereo = Standard_True;
~~~~~
~~~~
The following code configures the camera for stereographic rendering:
~~~~~{.cpp}
~~~~{.cpp}
// Create a Stereographic View in this Viewer
Handle(V3d_View) aView = new V3d_View (theViewer);
aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
@ -1689,15 +1689,15 @@ aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
aView->Camera()->SetIOD (IODType_Absolute, 5.0);
// Finally update the Visualization in this View
aView->Update();
~~~~~
~~~~
Other 3D displays are also supported, including row-interlaced with passive glasses and anaglyph glasses - see *Graphic3d_StereoMode* enumeration.
Example to activate another stereoscopic display:
~~~~~{.cpp}
~~~~{.cpp}
Handle(V3d_View) theView;
theView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
theView->ChangeRenderingParams().StereoParams = Graphic3d_StereoMode_RowInterlaced;
~~~~~
~~~~
Supporting of VR/AR headsets in application is more involving.
Class *Aspect_XRSession* defines a basic interface for working with extended reality.
@ -1716,26 +1716,26 @@ The following features support this method:
There are several types of background styles available for *V3d_View*: solid color, gradient color, image and environment cubemap.
To set solid color for the background you can use the following method:
~~~~~{.cpp}
~~~~{.cpp}
void V3d_View::SetBackgroundColor (const Quantity_Color& theColor);
~~~~~
~~~~
The gradient background style could be set up with the following method:
~~~~~{.cpp}
~~~~{.cpp}
void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
const Quantity_Color& theColor2,
const Aspect_GradientFillMethod theFillStyle,
const Standard_Boolean theToUpdate = false);
~~~~~
~~~~
The *theColor1* and *theColor2* parameters define the boundary colors of interpolation, the *theFillStyle* parameter defines the direction of interpolation.
To set the image as a background and change the background image style you can use the following method:
~~~~~{.cpp}
~~~~{.cpp}
void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
const Aspect_FillMethod theFillStyle,
const Standard_Boolean theToUpdate = false);
~~~~~
~~~~
The *theFileName* parameter defines the image file name and the path to it, the *theFillStyle* parameter defines the method of filling the background with the image.
The methods are:
@ -1793,7 +1793,7 @@ There are several ray-tracing options that user can switch on/off:
* Transparency shadow effects
Example:
~~~~~{.cpp}
~~~~{.cpp}
Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
// specifies rendering mode
aParams.Method = Graphic3d_RM_RAYTRACING;
@ -1809,7 +1809,7 @@ aParams.IsAntialiasingEnabled = true;
aParams.IsTransparentShadowEnabled = true;
// update the view
aView->Update();
~~~~~
~~~~
@subsubsection occt_visu_4_4_14 Display priorities
@ -1828,14 +1828,14 @@ In general, this function can be used for implementing "bring to front" function
Example:
~~~~~{.cpp}
~~~~{.cpp}
// set z-layer to an interactive object
Handle(AIS_InteractiveContext) theContext;
Handle(AIS_InteractiveObject) theInterObj;
Standard_Integer anId = -1;
aViewer->AddZLayer (anId);
theContext->SetZLayer (theInterObj, anId);
~~~~~
~~~~
For each z-layer, it is allowed to:
* Enable / disable depth test for layer.
@ -1847,7 +1847,7 @@ You can get the options using getter from *V3d_Viewer*.
It returns *Graphic3d_ZLayerSettings* for a given *LayerId*.
Example:
~~~~~{.cpp}
~~~~{.cpp}
// change z-layer settings
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
aSettings.SetEnableDepthTest (true);
@ -1855,7 +1855,7 @@ aSettings.SetEnableDepthWrite(true);
aSettings.SetClearDepth (true);
aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
aViewer->SetZLayerSettings (anId, aSettings);
~~~~~
~~~~
Another application for Z-Layer feature is treating visual precision issues when displaying objects far from the World Center.
The key problem with such objects is that visualization data is stored and manipulated with single precision floating-point numbers (32-bit).
@ -1887,10 +1887,10 @@ So, to apply this feature in OCCT, the application:
* Defines a Z-Layer for each spatial cell containing any object.
* Defines the Local Origin property of the Z-Layer according to the center of the cell.
~~~~~{.cpp}
~~~~{.cpp}
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
aSettings.SetLocalOrigin (400.0, 0.0, 0.0);
~~~~~
~~~~
* Assigns a presentable object to the nearest Z-Layer.
Note that Local Origin of the Layer is used only for rendering - everything outside will be still defined in the World Coordinate System,
@ -1906,29 +1906,29 @@ The *Graphic3d_ClipPlane* class provides the services for clipping planes:
it holds the plane equation coefficients and provides its graphical representation.
To set and get plane equation coefficients you can use the following methods:
~~~~~{.cpp}
~~~~{.cpp}
Graphic3d_ClipPlane::Graphic3d_ClipPlane (const gp_Pln& thePlane)
void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Equation& theEquation)
void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation)
gp_Pln Graphic3d_ClipPlane::ToPlane() const
~~~~~
~~~~
The clipping planes can be activated with the following method:
~~~~~{.cpp}
~~~~{.cpp}
void Graphic3d_ClipPlane::SetOn (const Standard_Boolean theIsOn)
~~~~~
~~~~
The number of clipping planes is limited.
You can check the limit value via method *Graphic3d_GraphicDriver::InquireLimit()*;
~~~~~{.cpp}
~~~~{.cpp}
// get the limit of clipping planes for the current view
Standard_Integer aMaxClipPlanes = aView->Viewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxNbClipPlanes);
~~~~~
~~~~
Let us see for example how to create a new clipping plane with custom parameters and add it to a view or to an object:
~~~~~{.cpp}
~~~~{.cpp}
// create a new clipping plane
Handle(Graphic3d_ClipPlane) aClipPlane = new Graphic3d_ClipPlane();
// change equation of the clipping plane
@ -1956,7 +1956,7 @@ aView->AddClipPlane (aClipPlane);
aClipPlane->SetOn (Standard_True);
// update the view
aView->Update();
~~~~~
~~~~
@subsubsection occt_visu_4_4_17 Automatic back face culling
@ -1989,7 +1989,7 @@ To create 3D graphic objects and display them in the screen, follow the procedur
Create colors.
~~~~~{.cpp}
~~~~{.cpp}
Quantity_Color aBlack (Quantity_NOC_BLACK);
Quantity_Color aBlue (Quantity_NOC_MATRABLUE);
Quantity_Color aBrown (Quantity_NOC_BROWN4);
@ -1999,21 +1999,21 @@ Quantity_Color aGray (Quantity_NOC_GRAY70);
Quantity_Color aMyColor (0.99, 0.65, 0.31, Quantity_TOC_RGB);
Quantity_Color aBeet (Quantity_NOC_BEET);
Quantity_Color aWhite (Quantity_NOC_WHITE);
~~~~~
~~~~
Create line attributes.
~~~~~{.cpp}
~~~~{.cpp}
Handle(Graphic3d_AspectLine3d) anAspectBrown = new Graphic3d_AspectLine3d();
Handle(Graphic3d_AspectLine3d) anAspectBlue = new Graphic3d_AspectLine3d();
Handle(Graphic3d_AspectLine3d) anAspectWhite = new Graphic3d_AspectLine3d();
anAspectBrown->SetColor (aBrown);
anAspectBlue ->SetColor (aBlue);
anAspectWhite->SetColor (aWhite);
~~~~~
~~~~
Create marker attributes.
~~~~~{.cpp}
~~~~{.cpp}
Handle(Graphic3d_AspectMarker3d aFirebrickMarker = new Graphic3d_AspectMarker3d();
// marker attributes
aFirebrickMarker->SetColor (Firebrick);
@ -2021,10 +2021,10 @@ aFirebrickMarker->SetScale (1.0f);
aFirebrickMarker->SetType (Aspect_TOM_BALL);
// or custom image
aFirebrickMarker->SetMarkerImage (theImage)
~~~~~
~~~~
Create facet attributes.
~~~~~{.cpp}
~~~~{.cpp}
Handle(Graphic3d_AspectFillArea3d) aFaceAspect = new Graphic3d_AspectFillArea3d();
Graphic3d_MaterialAspect aBrassMaterial (Graphic3d_NameOfMaterial_Brass);
Graphic3d_MaterialAspect aGoldMaterial (Graphic3d_NameOfMaterial_Gold);
@ -2033,16 +2033,16 @@ aFaceAspect->SetInteriorColor (aMyColor);
aFaceAspect->SetDistinguishOn ();
aFaceAspect->SetFrontMaterial (aGoldMaterial);
aFaceAspect->SetBackMaterial (aBrassMaterial);
~~~~~
~~~~
Create text attributes.
~~~~~{.cpp}
~~~~{.cpp}
Handle(Graphic3d_AspectText3d) aTextAspect = new Graphic3d_AspectText3d (aForest, Font_NOF_MONOSPACE, 1.0, 0.0);
~~~~~
~~~~
@subsubsection occt_visu_4_5_2 Create a 3D Viewer (a Windows example)
~~~~~{.cpp}
~~~~{.cpp}
// create a graphic driver
Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver (Handle(Aspect_DisplayConnection)());
// create a viewer
@ -2058,30 +2058,30 @@ a3DViewer->SetDefaultLights();
a3DViewer->SetLightOn();
// set background color to black
a3DViewer->SetDefaultBackgroundColor (Quantity_NOC_BLACK);
~~~~~
~~~~
@subsubsection occt_visu_4_5_3 Create a 3D view (a Windows example)
It is assumed that a valid Windows window may already be accessed via the method *GetSafeHwnd()* (as in case of MFC sample).
~~~~~{.cpp}
~~~~{.cpp}
Handle(WNT_Window) aWNTWindow = new WNT_Window (GetSafeHwnd());
myView = myViewer->CreateView();
myView->SetWindow (aWNTWindow);
~~~~~
~~~~
@subsubsection occt_visu_4_5_4 Create an interactive context
~~~~~{.cpp}
~~~~{.cpp}
myAISContext = new AIS_InteractiveContext (myViewer);
~~~~~
~~~~
You are now able to display interactive objects such as an *AIS_Shape*.
~~~~~{.cpp}
~~~~{.cpp}
TopoDS_Shape aShape = BRepAPI_MakeBox (10, 20, 30).Solid();
Handle(AIS_Shape) anAISShape = new AIS_Shape (aShape);
myAISContext->Display (anAISShape, true);
~~~~~
~~~~
@subsubsection occt_visu_4_5_5 Create your own interactive object
@ -2095,7 +2095,7 @@ i.e. in hidden line removal and wireframe modes.
Let us look at the example of compute methods
~~~~~{.cpp}
~~~~{.cpp}
void MyPresentableObject::Compute (const Handle(PrsMgr_PresentationManager)& thePrsManager,
const Handle(Graphic3d_Structure)& thePrs,
const Standard_Integer theMode)
@ -2108,25 +2108,25 @@ void MyPresentableObject::Compute (const Handle(Prs3d_Projector)& theProjector,
(
//...
)
~~~~~
~~~~
@subsubsection occt_visu_4_5_6 Create primitives in the interactive object
Get the group used in *Graphic3d_Structure*.
~~~~~{.cpp}
~~~~{.cpp}
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
~~~~~
~~~~
Update the group attributes.
~~~~~{.cpp}
~~~~{.cpp}
aGroup->SetGroupPrimitivesAspect (anAspectBlue);
~~~~~
~~~~
Create two triangles in *aGroup*.
~~~~~{.cpp}
~~~~{.cpp}
Standard_Integer aNbTria = 2;
Handle(Graphic3d_ArrayOfTriangles) aTriangles = new Graphic3d_ArrayOfTriangles (3 * aNbTria, 0, Graphic3d_ArrayFlags_VertexNormal);
for (Standard_Integer aTriIter = 1; aTriIter <= aNbTria; ++aTriIter)
@ -2137,11 +2137,11 @@ for (Standard_Integer aTriIter = 1; aTriIter <= aNbTria; ++aTriIter)
}
aGroup->AddPrimitiveArray (aTriangles);
aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectFillArea3d());
~~~~~
~~~~
Use the polyline function to create a boundary box for the *thePrs* structure in group *aGroup*.
~~~~~{.cpp}
~~~~{.cpp}
Standard_Real Xm, Ym, Zm, XM, YM, ZM;
thePrs->MinMaxValues (Xm, Ym, Zm, XM, YM, ZM);
@ -2169,11 +2169,11 @@ aPolylines->AddVertex (Xm, Ym, ZM);
aGroup->AddPrimitiveArray(aPolylines);
aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d());
~~~~~
~~~~
Create text and markers in group *aGroup*.
~~~~~{.cpp}
~~~~{.cpp}
static char* THE_TEXT[3] =
{
"Application title",
@ -2194,7 +2194,7 @@ for (int i = 0; i <= 2; i++)
-(Standard_Real )i * 4);
aGroup->Text (THE_TEXT[i], Marker, 20.);
}
~~~~~
~~~~
@section occt_visu_5 Mesh Visualization Services

View File

@ -168,38 +168,38 @@ To use XDE you have to set the environment variables properly. Make sure that tw
Before working with shapes, properties, and other types of information, the global organization of an XDE Document can be queried or completed to determine if an existing Document is actually structured for use with XDE.
To find out if an existing *TDocStd_Document* is suitable for XDE, use:
~~~~~
~~~~{.cpp}
Handle(TDocStd_Document) doc...
if ( XCAFDoc_DocumentTool::IsXCAFDocument (doc) ) { .. yes .. }
~~~~~
~~~~
If the Document is suitable for XDE, you can perform operations and queries explained in this guide. However, if a Document is not fully structured for XDE, it must be initialized.
@subsubsection occt_xde_2_1_3 Get an Application or an Initialized Document
If you want to retrieve an existing application or an existing document (known to be correctly structured for XDE), use:
~~~~~
~~~~{.cpp}
Handle(TDocStd_Document) aDoc;
Handle(XCAFApp_Application) anApp = XCAFApp_Application::GetApplication();
anApp->NewDocument(;MDTV-XCAF;,aDoc);
~~~~~
~~~~
@subsection occt_xde_2_2 Shapes and Assemblies
@subsubsection occt_xde_2_2_1 Initialize an XDE Document (Shapes)
An XDE Document begins with a *TDocStd_Document*. Assuming you have a *TDocStd_Document* already created, you can ensure that it is correctly structured for XDE by initializing the XDE structure as follows:
~~~~~
~~~~{.cpp}
Handle(TDocStd_Document) doc...
Handle (XCAFDoc_ShapeTool) myAssembly =
XCAFDoc_DocumentTool::ShapeTool (Doc->Main());
TDF_Label aLabel = myAssembly->NewShape()
~~~~~
~~~~
**Note** that the method *XCAFDoc_DocumentTool::ShapeTool* returns the *XCAFDoc_ShapeTool*. The first time this method is used, it creates the *XCAFDoc_ShapeTool*. In our example, a handle is used for the *TDocStd_Document*.
@subsubsection occt_xde_2_2_2 Get a Node considered as an Assembly
To get a node considered as an Assembly from an XDE structure, you can use the Label of the node. Assuming that you have a properly initialized *TDocStd_Document*, use:
~~~~~
~~~~{.cpp}
Handle(TDocStd_Document) doc...
Handle(XCAFDoc_ShapeTool) myAssembly = XCAFDoc_DocumentTool::ShapeTool (aLabel);
~~~~~
~~~~
In the previous example, you can also get the Main Item of an XDE document, which records the root shape representation (as a Compound if it is an Assembly) by using *ShapeTool(Doc->Main())* instead of *ShapeTool(aLabel)*.
You can then query or edit this Assembly node, the Main Item or another one (*myAssembly* in our examples).
@ -210,9 +210,9 @@ You can then query or edit this Assembly node, the Main Item or another one (*my
Some actions in this chapter affect the content of the document, considered as an Assembly. As a result, you will sometimes need to update various representations (including the compounds).
To update the representations, use:
~~~~~
~~~~{.cpp}
myAssembly->UpdateAssemblies();
~~~~~
~~~~
This call performs a top-down update of the Assembly compounds stored in the document.
**Note** that you have to run this method manually to actualize your Assemblies after any low-level modifications on shapes.
@ -230,29 +230,29 @@ A shape to be added can be defined as a compound (if required), with the followi
* If the Shape is not a compound, it is taken as a whole, without breaking it down.
To break down a Compound in the assembly structure, use:
~~~~~
~~~~{.cpp}
Standard_Boolean makeAssembly;
// True to interpret a Compound as an Assembly,
// False to take it as a whole
aLabel = myAssembly->AddShape(aShape, makeAssembly);
~~~~~
~~~~
Each node of the assembly therefore refers to its sub-shapes.
Concerning located instances of sub-shapes, the corresponding shapes, (without location) appear at distinct sub-labels. They are referred to by a shape instance, which associates a location.
@subsubsection occt_xde_2_2_5 Setting a given Shape at a given Label
A top-level shape can be changed. In this example, no interpretation of compound is performed:
~~~~~
~~~~{.cpp}
Standard_CString LabelString ...;
// identifies the Label (form ;0:i:j...;)
TDF_Label aLabel...;
// A label must be present
myAssembly->SetShape(aLabel, aShape);
~~~~~
~~~~
@subsubsection occt_xde_2_2_6 Getting a Shape from a Label
To get a shape from its Label from the top-level, use:
~~~~~
~~~~{.cpp}
TDF_Label aLabel...
// A label must be present
if (aLabel.IsNull()) {
@ -263,19 +263,19 @@ aShape = myAssembly->GetShape(aLabel);
if (aShape.IsNull()) {
// this label is not for a Shape
}
~~~~~
~~~~
**Note** that if the label corresponds to an assembly, the result is a compound.
@subsubsection occt_xde_2_2_7 Getting a Label from a Shape
To get a Label, which is attached to a Shape from the top-level, use:
~~~~~
~~~~{.cpp}
Standard_Boolean findInstance = Standard_False;
// (this is default value)
aLabel = myAssembly->FindShape(aShape [,findInstance]);
if (aLabel.IsNull()) {
// no label found for this shape
}
~~~~~
~~~~
If *findInstance* is True, a search is made for the shape with the same location. If it is False (default value), a search is made among original, non-located shapes.
@subsubsection occt_xde_2_2_8 Other Queries on a Label
@ -284,29 +284,29 @@ Various other queries can be made from a Label within the Main Item of XDE:
#### Main Shapes
To determine if a Shape is recorded (or not), use:
~~~~~
~~~~{.cpp}
if ( myAssembly->IsShape(aLabel) ) { .. yes .. }
~~~~~
~~~~
To determine if the shape is top-level, i.e. was added by the *AddShape* method, use:
~~~~~
~~~~{.cpp}
if ( myAssembly->IsTopLevel(aLabel) ) { .. yes .. }
~~~~~
~~~~
To get a list of top-level shapes added by the *AddShape* method, use:
~~~~~
~~~~{.cpp}
TDF_LabelSequence frshapes;
myAssembly->GetShapes(frshapes);
~~~~~
~~~~
To get all free shapes at once if the list above has only one item, use:
~~~~~
~~~~{.cpp}
TopoDS_Shape result = myAssembly->GetShape(frshapes.Value(1));
~~~~~
~~~~
If there is more than one item, you must create and fill a compound, use:
~~~~~
~~~~{.cpp}
TopoDS_Compound C;
BRep_Builder B;
B.MakeCompound(C);
@ -314,72 +314,72 @@ for(Standard_Integer i=1; i=frshapes.Length(); i++) {
TopoDS_Shape S = myAssembly->GetShape(frshapes.Value(i));
B.Add(C,S);
}
~~~~~
~~~~
In our example, the result is the compound C.
To determine if a shape is a free shape (no reference or super-assembly), use:
~~~~~
~~~~{.cpp}
if ( myAssembly->IsFree(aLabel) ) { .. yes .. }
~~~~~
~~~~
To get a list of Free Shapes (roots), use:
~~~~~
~~~~{.cpp}
TDF_LabelSequence frshapes;
myAssembly->GetFreeShapes(frshapes);
~~~~~
~~~~
To get the shapes, which use a given shape as a component, use:
~~~~~
~~~~{.cpp}
TDF_LabelSequence users;
Standard_Integer nbusers = myAssembly->GetUsers(aLabel,users);
~~~~~
~~~~
The count of users is contained with *nbusers*. It contains 0 if there are no users.
#### Assembly and Components
To determine if a label is attached to the main part or to a sub-part (component), use:
~~~~~
~~~~{.cpp}
if (myAssembly->IsComponent(aLabel)) { .. yes .. }
~~~~~
~~~~
To determine whether a label is a node of a (sub-) assembly or a simple shape, use:
~~~~~
~~~~{.cpp}
if ( myAssembly->IsAssembly(aLabel) ) { .. yes .. }
~~~~~
~~~~
If the label is a node of a (sub-) assembly, you can get the count of components, use:
~~~~~
~~~~{.cpp}
Standard_Boolean subchilds = Standard_False; //default
Standard_Integer nbc = myAssembly->NbComponents (aLabel [,subchilds]);
~~~~~
~~~~
If *subchilds* is True, commands also consider sub-levels. By default, only level one is checked.
To get component Labels themselves, use:
~~~~~
~~~~{.cpp}
Standard_Boolean subchilds = Standard_False; //default
TDF_LabelSequence comps;
Standard_Boolean isassembly = myAssembly->GetComponents
(aLabel,comps[,subchilds]);
~~~~~
~~~~
@subsubsection occt_xde_2_2_9 Instances and References for Components
To determine if a label is a simple shape, use:
~~~~~
~~~~{.cpp}
if ( myAssembly->IsSimpleShape(aLabel) ) { .. yes .. }
~~~~~
~~~~
To determine if a label is a located reference to another one, use:
~~~~~
~~~~{.cpp}
if ( myAssembly->IsReference(aLabel) ) { .. yes .. }
~~~~~
~~~~
If the label is a located reference, you can get the location, use:
~~~~~
~~~~{.cpp}
TopLoc_Location loc = myAssembly->GetLocation (aLabel);
~~~~~
~~~~
To get the label of a referenced original shape (also tests if it is a reference), use:
~~~~~
~~~~{.cpp}
Standard_Boolean isref = myAssembly->GetReferredShape
(aLabel, refLabel);
~~~~~
~~~~
**Note** *isref* returns False if *aLabel* is not for a reference.
@ -387,55 +387,55 @@ Standard_Boolean isref = myAssembly->GetReferredShape
In addition to the previously described *AddShape* and *SetShape*, several shape edits are possible.
To remove a Shape, and all its sub-labels, use:
~~~~~
~~~~{.cpp}
Standard_Boolean remsh = myAssembly->RemoveShape(aLabel);
// remsh is returned True if done
~~~~~
~~~~
This operation will fail if the shape is neither free nor top level.
To add a Component to the Assembly, from a new shape, use:
~~~~~
~~~~{.cpp}
Standard_Boolean expand = Standard_False; //default
TDF_Label aLabel = myAssembly->AddComponent (aShape [,expand]);
~~~~~
~~~~
If *expand* is True and *aShape* is a Compound, *aShape* is broken down to produce sub-components, one for each of its sub-shapes.
To add a component to the assembly, from a previously recorded shape (the new component is defined by the label of the reference shape, and its location), use:
~~~~~
~~~~{.cpp}
TDF_Label refLabel ...; // the label of reference shape
TopLoc_Location loc ...; // the desired location
TDF_Label aLabel = myAssembly->AddComponent (refLabel, loc);
~~~~~
~~~~
To remove a component from the assembly, use:
~~~~~
~~~~{.cpp}
myAssembly->RemoveComponent (aLabel);
~~~~~
~~~~
@subsection occt_xde_2_4 Management of Sub-Shapes
In addition to components of a (sub-)assembly, it is possible to have individual identification of some sub-shapes inside any shape. Therefore, you can attach specific attributes such as Colors. Some additional actions can be performed on sub-shapes that are neither top-level, nor components:
To add a sub-shape to a given Label, use:
~~~~~
~~~~{.cpp}
TDF_Label subLabel = myAssembly->AddSubShape (aLabel, subShape);
~~~~~
~~~~
To find the Label attached to a given sub-shape, use:
~~~~~
~~~~{.cpp}
TDF_Label subLabel; // new label to be computed
if ( myAssembly-> FindSubShape (aLabel, subShape, subLabel)) { .. yes .. }
~~~~~
~~~~
If the sub-shape is found (yes), *subLabel* is filled by the correct value.
To find the top-level simple shape (not a compound whether free or not), which contains a given sub-shape, use:
~~~~~
~~~~{.cpp}
TDF_Label mainLabel = myAssembly->FindMainShape(subShape);
~~~~~
~~~~
**Note** that there should be only one shape for a valid model. In any case, the search stops on the first one found.
To get the sub-shapes of a shape, which are recorded under a label, use:
~~~~~
~~~~{.cpp}
TDF_LabelSequence subs;
Standard_Boolean hassubs = myAssembly->GetSubShapes (aLabel,subs);
~~~~~
~~~~
@subsection occt_xde_2_5 Properties
Some properties can be attached directly to shapes. These properties are:
* Name (standard definition from OCAF)
@ -458,22 +458,22 @@ Name is implemented and used as a *TDataStd_Name*, which can be attached to any
These considerations are not specific to XDE. What is specific to data exchange is the way names are attached to entities.
To get the name attached to a label (as a reminder using OCAF), use:
~~~~~
~~~~{.cpp}
Handle(TDataStd_Name) N;
if ( !aLabel.FindAttribute(TDataStd_Name::GetID(),N)) {
// no name is attached
}
TCollection_ExtendedString name = N->Get();
~~~~~
~~~~
Don't forget to consider Extended String as ASCII, for the exchange file.
To set a name to a label (as a reminder using OCAF), use:
~~~~~
~~~~{.cpp}
TCollection_ExtendedString aName ...;
// contains the desired name for this Label (ASCII)
TDataStd_Name::Set (aLabel, aName);
~~~~~
~~~~
@subsubsection occt_xde_2_5_2 Centroid
A Centroid is defined by a Point to fix its position. It is handled as a property, item of the class *XCAFDoc_Centroid*, sub-class of *TDF_Attribute*. However, global methods give access to the position itself.
@ -483,26 +483,26 @@ This notion has been introduced in STEP, together with that of Volume, and Area,
A centroid can be determined at any level of an assembly, thereby allowing a check of both individual simple shapes and their combinations including locations.
To get a Centroid attached to a Shape, use:
~~~~~
~~~~{.cpp}
gp_Pnt pos;
Handle(XCAFDoc_Centroid) C;
aLabel.FindAttribute ( XCAFDoc_Centroid::GetID(), C );
if ( !C.IsNull() ) pos = C->Get();
~~~~~
~~~~
To set a Centroid to a Shape, use:
~~~~~
~~~~{.cpp}
gp_Pnt pos (X,Y,Z);
// the position previously computed for the centroid
XCAFDoc_Centroid::Set ( aLabel, pos );
~~~~~
~~~~
@subsubsection occt_xde_2_5_3 Area
An Area is defined by a Real, it corresponds to the computed Area of a Shape, provided that it contains surfaces. It is handled as a property, item of the class *XCAFDoc_Area*, sub-class of *TDF_Attribute*.
This notion has been introduced in STEP but it is usually disregarded for a Solid, as Volume is used instead. In addition, it is attached to simple shapes, not to assemblies.
To get an area attached to a Shape, use:
~~~~~
~~~~{.cpp}
Standard_Real area;
Handle(XCAFDoc_Area) A;
L.FindAttribute ( XCAFDoc_Area::GetID(), A );
@ -512,25 +512,25 @@ To set an area value to a Shape, use:
Standard_Real area ...;
// value previously computed for the area
XCAFDoc_Area::Set ( aLabel, area );
~~~~~
~~~~
@subsubsection occt_xde_2_5_4 Volume
A Volume is defined by a Real and corresponds to the computed volume of a Shape, provided that it contains solids. It is handled as a property, an item of the class *XCAFDoc_Volume*, sub-class of *TDF_Attribute*.
This notion has been introduced in STEP. It may be attached to simple shapes or their assemblies for computing cumulated volumes and centers of gravity.
To get a Volume attached to a Shape, use:
~~~~~
~~~~{.cpp}
Standard_Real volume;
Handle(XCAFDoc_Volume) V;
L.FindAttribute ( XCAFDoc_Volume::GetID(), V );
if ( !V.IsNull() ) volume = V->Get();
~~~~~
~~~~
To set a volume value to a Shape, use:
~~~~~
~~~~{.cpp}
Standard_Real volume ...;
// value previously computed for the volume
XCAFDoc_Volume::Set ( aLabel, volume );
~~~~~
~~~~
@subsection occt_xde_2_6 Colors and Layers
XDE can read and write colors and layers assigned to shapes or their subparts (down to level of faces and edges) to and from both IGES and STEP formats.
@ -553,10 +553,10 @@ These definitions are common to various exchange formats, at least for STEP and
@subsubsection occt_xde_2_6_1 Initialization
To query, edit, or initialize a Document to handle Colors of XCAF, use:
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_ColorTool) myColors =
XCAFDoc_DocumentTool::ColorTool(Doc->Main ());
~~~~~
~~~~
This call can be used at any time. The first time it is used, a relevant structure is added to the document. This definition is used for all the following color calls and will not be repeated for these.
@subsubsection occt_xde_2_6_2 Adding a Color
@ -566,7 +566,7 @@ There are two ways to add a color. You can:
When the Color is added by its value *Quantity_Color*, it is added only if it has not yet been recorded (same RGB values) in the Document.
To set a Color to a Shape using a label, use:
~~~~~
~~~~{.cpp}
Quantity_Color Col (red,green,blue);
XCAFDoc_ColorType ctype ..;
// can take one of these values :
@ -574,60 +574,60 @@ XCAFDoc_ColorType ctype ..;
// XCAFDoc_ColorSurf : surfaces only
// XCAFDoc_ColorCurv : curves only
myColors->SetColor ( aLabel, Col, ctype );
~~~~~
~~~~
Alternately, the Shape can be designated directly, without using its label, use:
~~~~~
~~~~{.cpp}
myColors->SetColor ( aShape, Col, ctype );
// Creating and Adding a Color, explicitly
Quantity_Color Col (red,green,blue);
TDF_Label ColLabel = myColors->AddColor ( Col );
~~~~~
~~~~
**Note** that this Color can then be named, allowing later retrieval by its Name instead of its Value.
To set a Color, identified by its Label and already recorded, to a Shape, use:
~~~~~
~~~~{.cpp}
XCAFDoc_ColorType ctype ..; // see above
if ( myColors->SetColors ( aLabel, ColLabel, ctype) ) {.. it is done .. }
~~~~~
~~~~
In this example, *aLabel* can be replaced by *aShape* directly.
@subsubsection occt_xde_2_6_3 Queries on Colors
Various queries can be performed on colors. However, only specific queries are included in this section, not general queries using names.
To determine if a Color is attached to a Shape, for a given color type (ctype), use:
~~~~~
~~~~{.cpp}
if ( myColors->IsSet (aLabel , ctype)) {
// yes, there is one ..
}
~~~~~
~~~~
In this example, *aLabel* can be replaced by *aShape* directly.
To get the Color attached to a Shape (for any color type), use:
~~~~~
~~~~{.cpp}
Quantity_Color col;
// will receive the recorded value (if there is some)
if ( !myColors->GetColor(aLabel, col) ) {
// sorry, no color ..
}
~~~~~
~~~~
Color name can also be queried from *col.StringName* or *col.Name*.
In this example, *aLabel* can be replaced by *aShape* directly.
To get the Color attached to a Shape, with a specific color type, use:
~~~~~
~~~~{.cpp}
XCAFDoc_ColorType ctype ..;
Quantity_Color col;
// will receive the recorded value (if there is some)
if ( !myColors->GetColor(aLabel, ctype, col) ) {
// sorry, no color ..
}
~~~~~
~~~~
To get all the Colors recorded in the Document, use:
~~~~~
~~~~{.cpp}
Quantity_Color col; // to receive the values
TDF_LabelSequence ColLabels;
myColors->GetColors(ColLabels);
@ -637,28 +637,28 @@ for (i = 1; i = nbc; i ++) {
if ( !myColors->GetColor(aLabel, col) ) continue;
// col receives the color n0 i ..
}
~~~~~
~~~~
To find a Color from its Value, use:
~~~~~
~~~~{.cpp}
Quantity_Color Col (red,green,blue);
TDF_Label ColLabel = myColors-FindColor (Col);
if ( !ColLabel.IsNull() ) { .. found .. }
~~~~~
~~~~
@subsubsection occt_xde_2_6_4 Editing Colors
Besides adding colors, the following attribute edits can be made:
To unset a Color on a Shape, use:
~~~~~
~~~~{.cpp}
XCAFDoc_ColorType ctype ...;
// desired type (XCAFDoc_ColorGen for all )
myColors->UnSetColor (aLabel,ctype);
~~~~~
~~~~
To remove a Color and all the references to it (so that the related shapes will become colorless), use:
~~~~~
~~~~{.cpp}
myColors->RemoveColor(ColLabel);
~~~~~
~~~~
@subsection occt_xde_2_7 Geometric Dimensions & Tolerances (GD\&T)
@ -683,10 +683,10 @@ 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:
~~~~~
~~~~{.cpp}
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.
@subsubsection occt_xde_2_7_2 Adding a GD\&T
@ -699,19 +699,19 @@ All methods create a sub-label for the corresponding GD\&T entity of the tool ma
created entity.
Here is an example of adding a new dimension:
~~~~~
~~~~{.cpp}
TDF_Label aDimLabel = myDimTolTool->AddDimension();
if (!aDimLabel.IsNull())
{
// error processing
}
~~~~~
~~~~
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
below, where the dimension becomes a linear distance between two points.
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_Dimension) aDimAttr;
aDimLabel.FindAttribute(XCAFDoc_Dimension::GetID(), aDimAttr);
if (!aDimAttr.IsNull())
@ -725,7 +725,7 @@ if (!aDimAttr.IsNull())
//...
aDimAttr->SetObject(aDimObject);
}
~~~~~
~~~~
A similar approach can be used for other GD\&T types.
@subsubsection occt_xde_2_7_4 Linking GD\&Ts
@ -737,14 +737,14 @@ To link a GD\&T entity with other OCAF labels (e.g. representing shapes) one sho
These methods can take a single label or a sequence of labels. All previous links will be removed.
The example below demonstrates linking of a dimension to sequences of shape labels:
~~~~~
~~~~{.cpp}
TDF_LabelSequence aShapes1, aShapes2;
aShapes1.Append(aShape11);
//...
aShapes2.Append(aShape21);
//...
aDGTTool->SetDimension(aShapes1, aShapes2, aDimLabel);
~~~~~
~~~~
In addition, a special method *SetDatumToGeomTol* should be used to link a datum with a geometric tolerance.
@ -772,14 +772,14 @@ Custom data can be stored in labels with tags beyond the ranges listed above.
In an XDE document, Clipping planes are managed by the class *XCAFDoc_ClippingPlaneTool*. 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. Clipping planes are stored in a child of the starting document label 0.1.8, where planes themselves are defined as *TDataXtd_Plane* attribute. *TDataStd_Name* attribute is used for naming.
To query, edit, or initialize a Document to handle clipping planes of XCAF, use:
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_ClippingPlaneTool) myClipPlaneTool =
XCAFDoc_DocumentTool::ClippingPlaneTool(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.
To add a clipping plane use one of overloaded methods *AddClippingPlane*, e.g.:
~~~~~
~~~~{.cpp}
gp_Pln aPln = ...
Standard_Boolean aCapping = ...
TDF_Label aClipPlnLbl = myClipPlaneTool->AddClippingPlane(aPln, "Name of plane", aCapping);
@ -787,31 +787,31 @@ if (aClipPlnLbl.IsNull())
{
// error processing
}
~~~~~
~~~~
To remove a plane use *RemoveClippingPlane* method, e.g.:
~~~~~
~~~~{.cpp}
if (!myClipPlaneTool->RemoveClippingPlane(aClipPlnLbl))
{
// not removed
}
~~~~~
~~~~
The plane will not be removed if it is referenced in at least one view.
To change the clipping plane and its name use *UpdateClippingPlane* method, e.g.:
~~~~~
~~~~{.cpp}
gp_Pln aPln = ...
myClipPlaneTool->UpdateClippingPlane(aClipPlnLbl, aPln, "New name of plane");
~~~~~
~~~~
Capping property can be changed using *SetCapping* method, e.g.:
~~~~~
~~~~{.cpp}
Standard_Boolean aCapping = ...
myClipPlaneTool->SetCapping(aClipPlnLbl, aCapping);
~~~~~
~~~~
*XCAFDoc_ClippingPlaneTool* can be used to get all clipping plane labels and to check if a label belongs to the *ClippingPlane table*, e.g.:
~~~~~
~~~~{.cpp}
TDF_LabelSequence aClipPlaneLbls;
myClipPlaneTool->GetClippingPlanes(aClipPlaneLbls);
...
@ -830,21 +830,21 @@ 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 by Graph Nodes.
To query, edit, or initialize a Document to handle views of XCAF, use:
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_ViewTool) myViewTool =
XCAFDoc_DocumentTool::ViewTool(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.
To add a view use *AddView* method and an access *XCAFView_Object* object to set camera parameters, e.g.:
~~~~~
~~~~{.cpp}
TDF_Label aViewLbl = myViewTool->AddView();
if (aViewLbl.IsNull())
{
@ -862,22 +862,22 @@ if (!aViewAttr.IsNull())
...
aViewAttr->SetObject(aViewObject);
}
~~~~~
~~~~
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.
~~~~~
~~~~{.cpp}
TDF_LabelSequence aShapes; ...
TDF_LabelSequence aGDTs; ...
myViewTool->SetView(aShapes, aGDTs, aViewLbl);
TDF_LabelSequence aClippingPlanes; ...
myViewTool->SetClippingPlanes(aClippingPlanes, aViewLbl);
~~~~~
~~~~
To remove a view use *RemoveView* method.
To get all view labels and check if a label belongs to the View table use:
~~~~~
~~~~{.cpp}
TDF_LabelSequence aViewLbls;
myViewTool->GetViewLabels(aViewLbls);
...
@ -889,7 +889,7 @@ 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:
* *GetRefShapeLabel* - returns a sequence of associated shape labels;
@ -920,10 +920,10 @@ Notes binding is done through *XCAFDoc_GraphNode* attribute.
@subsubsection occt_xde_2_10_1 Initialization
To query, edit, or initialize a Document to handle custom notes of XCAF, use:
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_NotesTool) myNotes =
XCAFDoc_DocumentTool::NotesTool(Doc->Main ());
~~~~~
~~~~
This call can be used at any time. The first time it is used, a relevant structure is added to the document. This definition is used for all later notes calls and will not be repeated for them.
@subsubsection occt_xde_2_10_2 Creating Notes
@ -933,25 +933,25 @@ Before annotating a Document item a note must be created using one of the follow
- *CreateBinData* : creates a note with arbitrary binary data, e.g. contents of a file.
Both methods return an instance of *XCAFDoc_Note* class.
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_NotesTool) myNotes = ...
Handle(XCAFDoc_Note) myNote = myNotes->CreateComment("User", "Timestamp", "Hello, World!");
~~~~~
~~~~
This code adds a child label to label 0.1.9.1 with *XCAFDoc_NoteComment* attribute.
@subsubsection occt_xde_2_10_3 Editing a Note
An instance of *XCAFDoc_Note* class can be used for note editing.
One may change common note data.
~~~~~
~~~~{.cpp}
myNote->Set("New User", "New Timestamp");
~~~~~
~~~~
To change specific data one needs to down cast *myNote* handle to the appropriate sub-class:
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_NoteComment) myCommentNote = Handle(XCAFDoc_NoteComment)::DownCast(myNote);
if (!myCommentNote.IsNull()) {
myCommentNote->Set("New comment");
}
~~~~~
~~~~
In order to edit auxiliary note data such as text and attachment position, plane for rendering and tessellated presentation,
one should use a transfer object *XCAFNoteObjects_NoteObject* by GetObject and SetObject methods of *XCAFDoc_Note* class.
*XCAFNoteObjects_NoteObject* class provides the following functionality:
@ -961,7 +961,7 @@ one should use a transfer object *XCAFNoteObjects_NoteObject* by GetObject and S
- GetPresentation and SetPresentation methods allow to test for and specify tessellated presentation
After getting, the transfer object can be edited and set back to the note:
~~~~~
~~~~{.cpp}
Handle(XCAFNoteObjects_NoteObject) aNoteObj = myNote->GetObject();
if (!aNoteObj.IsNull())
{
@ -971,7 +971,7 @@ if (!aNoteObj.IsNull())
aNoteObj->SetPresentation (aS);
myNote->SetObject (aNoteObj);
}
~~~~~
~~~~
@subsubsection occt_xde_2_10_4 Adding Notes
@ -981,7 +981,7 @@ Once a note has been created it can be bound to a Document item using the follow
- *AddNoteToSubshape* : binds a note to a sub-shape.
All methods return a pointer to *XCAFDoc_AssemblyItemRef* attribute identifying the annotated item.
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_NotesTool) myNotes = ...
Handle(XCAFDoc_Note) myNote = ...
TDF_Label theLabel; ...
@ -990,7 +990,7 @@ Standard_GUID theAttrGUID; ...
Handle(XCAFDoc_AssemblyItemRef) myRefAttr = myNotes->AddNoteToAttr(myNote->Label(), theAttrGUID);
Standard_Integer theSubshape = 1;
Handle(XCAFDoc_AssemblyItemRef) myRefSubshape = myNotes->AddNoteToSubshape(myNote->Label(), theSubshape);
~~~~~
~~~~
This code adds three child labels with *XCAFDoc_AssemblyItemRef* attribute to label 0.1.9.2. *XCAFDoc_GraphNode* attributes are added to the child labels and note labels.
@subsubsection occt_xde_2_10_5 Finding Notes
@ -1000,7 +1000,7 @@ To find annotation labels under label 0.1.9.2 use the following *XCAFDoc_NotesTo
- *FindAnnotatedItemAttr* : returns an annotation label for a label's attribute;
- *FindAnnotatedItemSubshape* : returns an annotation label for a sub-shape.
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_NotesTool) myNotes = ...
TDF_Label theLabel; ...
TDF_Label myLabel = myNotes->FindAnnotatedItem(theLabel);
@ -1008,7 +1008,7 @@ Standard_GUID theAttrGUID; ...
TDF_Label myLabelAttr = myNotes->FindAnnotatedItemAttr(theLabel, theAttrGUID);
Standard_Integer theSubshape = 1;
TDF_Label myLabelSubshape = myNotes->FindAnnotatedItemSubshape(theLabel, theSubshape);
~~~~~
~~~~
Null label will be returned if there is no corresponding annotation.
To get all notes of the Document item use the following *XCAFDoc_NotesTool* methods:
@ -1017,7 +1017,7 @@ To get all notes of the Document item use the following *XCAFDoc_NotesTool* meth
- *GetAttrSubshape* : outputs a sequence of note labels bound to a sub-shape.
All these methods return the number of notes.
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_NotesTool) myNotes = ...
TDF_Label theLabel; ...
TDF_LabelSequence theNotes;
@ -1028,7 +1028,7 @@ myNotes->GetAttrNotes(theLabel, theAttrGUID, theNotesAttr);
Standard_Integer theSubshape = 1;
TDF_LabelSequence theNotesSubshape;
myNotes->GetAttrSubshape(theLabel, theSubshape, theNotesSubshape);
~~~~~
~~~~
@subsubsection occt_xde_2_10_6 Removing Notes
@ -1037,7 +1037,7 @@ To remove a note use one of the following *XCAFDoc_NotesTool* methods:
- *RemoveAttrNote* : unbinds a note from a label's attribute;
- *RemoveSubshapeNote* : unbinds a note from a sub-shape.
~~~~~
~~~~{.cpp}
Handle(XCAFDoc_Note) myNote = ...
TDF_Label theLabel; ...
myNotes->RemoveNote(myNote->Label(), theLabel);
@ -1045,7 +1045,7 @@ Standard_GUID theAttrGUID; ...
myRefAttr = myNotes->RemoveAttrNote(myNote->Label(), theAttrGUID);
Standard_Integer theSubshape = 1;
myNotes->RemoveSubshapeNote(myNote->Label(), theSubshape);
~~~~~
~~~~
A note will not be deleted automatically.
Counterpart methods to remove all notes are available, too.
@ -1074,7 +1074,7 @@ The packages to manage this are *IGESCAFControl* for IGES, and *STEPCAFControl*
@subsubsection occt_xde_2_11_1 Reading a STEP file
To read a STEP file by itself, use:
~~~~~
~~~~{.cpp}
STEPCAFControl_Reader reader;
IFSelect_ReturnStatus readstat = reader.ReadFile(filename);
// The various ways of reading a file are available here too :
@ -1089,13 +1089,13 @@ if ( !reader.Transfer ( doc ) ) {
}
// Here, the Document has been filled from a STEP file,
// it is ready to use
~~~~~
~~~~
In addition, the reader provides methods that are applicable to document transfers and for directly querying of the data produced.
@subsubsection occt_xde_2_11_2 Writing a STEP file
To write a STEP file by itself, use:
~~~~~
~~~~{.cpp}
STEPControl_StepModelType mode =
STEPControl_AsIs;
// Asis is the recommended value, others are available
@ -1111,7 +1111,7 @@ if ( ! writer.Transfer ( Doc, mode ) ) {
}
// Writing the File
IFSelect_ReturnStatus stat = writer.Write(file-name);
~~~~~
~~~~
@subsubsection occt_xde_2_11_3 Reading an IGES File
Use the same procedure as for a STEP file but with IGESCAFControl instead of STEPCAFControl.