TSNLib Tutorial

Contents

Tutorial Overview

Please note that prior to using this tutorial you should understand the basics of the Geometry Tutorial prior to looking at this tutorial.

This Tutorial is designed as a set of exercises for the programmer to either work through or browse.    This tutorial assumes a basic knowledge of the C++ language and some understanding of NURBS curves, surfaces, trimmed surfaces and solids.  All of the source code in this tutorial is working code which can be found in the specified locations.   

Much of the source code shown here are portions of software we utilized for software testing, You may ignore the portions of the code which measure the time, number of surface evaluations and print the global solver statistics.

Trimmed Surface Creation Tutorial

Creating correctly defined trimmed surfaces is essential. There are two different ways in which trimmed surfaces may be created. First you may create a trimmed surface (or face) directly from a surface and its parametric domain (IwBrep::CreateFaceFromSurface). You may also create a trimmed surface from the surface and a set of oriented boundary curves. This tutorial shows how this may be done. Our tutorial demonstrates the creation of a trimmed surface from class (IwCurveBoundedSurface) which mirrors the IGES trimmed surface structure. This code is actually used in our IGES processor to create trimmed surfaces. Note that this code allows you to add a trimmed surface to an already existing brep. It is possible to put multiple trimmed surfaces in a single brep. You need to first create a brep prior to invoking this method. The following code shows how you might set up a brep prior to calling the function:

IwBrep *pBrep = new (sContext) IwBrep();
pBrep->SetTolerance(d3DToleranceForThisBrep);

Example 1. Creation of Planar Face With  Two Holes.

See source code for  my_test_tsurf_creation() in  iwtopo_test.cpp

Example 2. Creation of Planar Face With Two holes

You may see how the curve bounded surface is setup in IwIgesReader.cpp. Search for 144 or 143. The following example demonstrates the creation of a single trimmed surface (IwFace) in a brep given a set of trimming loops from the curve bounded surface.

See source code for  CreateTrimmedSurfaceInBrep() in  IwCurveBoundedSurface::CreateTrimmedSurfaceInBrep ()    

Trimmed Surface Query Tutorial

The following code segment is extracted from IwFace::Draw. It demonstrates how to extract the trimming information from the face and invoke the drawing routines to create an OpenGL trimmed surface. To get the face(s) of a brep use IwBrep::GetFaces.

See Source code for Case 4 in IwFace::OutputGraphics ()  IwFace.cpp

Parsing the IwSolution Object

The IwTopologySolver (demonstrated below) produces an IwSolutionArray to store the result of a global solve. The IwSolutionArray is an array of IwSolution objects that represent individual solution points to the global problem being solved. To utilize the IwTopologySolver you will need to parse the IwSolution object to extract the required data. The IwSolution contains the objects (face, curve, edge, vertex) that yielded the given solution and corresponding parameteric values. This function demonstrates how to extract that information from the IwSolution and create a corresponding 3D point.

See Source code for get_point_from_sol () in: iwtopo_test.cpp

Trimmed Surface/Point Solver Tutorial

The following code demonstrates the use of the IwTopologySolver to solve an operation between a brep and a point. This solver allows the user to find intersections (IW_SO_INTERSECT), minimum/maximum distance between the brep and the point (IW_SO_MINIMIZE/>IW_SO_MAXIMIZE), and points were the tangent plane of the trimmed surface is perpendicular to the vector to the point (IW_SO_NORMALIZE.

See Source code for my_test_tsurface_point_extrema() in: iwtopo_test.cpp

Trimmed Surface/Curve Solver Tutorial

The following code demonstrates the use of the IwTopologySolver to solve an operation between a brep and a curve. This solver allows the user to find intersections (W_SO_INTERSECT, minimum/maximum distance between the brep and the curve (IW_SO_MINIMIZE IW_SO_MAXIMIZE), and points were the tangent plane of the trimmed surface and the tangent of the curve are perpendicular to the vector between the trimmed surface and the curve (IW_SO_NORMALIZE).

See Source code for my_test_tsurface_curve_solve() in: iwtopo_test.cp

Trimmed Surface/Trimmed Surface Solver Tutorial

The following code demonstrates the use of the IwTopologySolver to solve an operation between two breps with trimmed surfaces. This solver allows the user to find the minimum/maximum distance between two breps with trimmed surfaces(IW_SO_MINIMIZE IW_SO_MAXIMIZE, and points were the tangent planes of the trimmed surfaces of each are perpendicular to the vector between the two trimmed surface (IW_SO_NORMALIZE).

See Source code for my_test_tsurface_tsurface_solve()iwtopo_test.cpp

Planar Sectioning Tutorial

This tutorial demonstrates how to do planar sectioning of a brep with trimmed surfaces. It creates a set of planes which span the bounding box of the brep and uses them to section the brep.

See Source code for my_test_tsurf_section()  in: iwtopo_test.cpp

Point Classification Tutorial

This tutorial demonstrates the classification of a parameter space point on a surface relative to the surface boundary. The function creates a grid of points in the parameter space of the surface and classifies them.

See Source code for  my_test_tsurface_point_classify() iwtopo_test.cpp

Curve Classification Tutorial

This tutorial demonstrates the classification of a 2D curve relative to the boundary of a trimmed surface. Please note that the method being demonstrated here also allows you to specify a 3D curve. The method will automatically choose the correct place to classify the curve based on its dimension.

See Source code for  my_test_tsurface_curve_classify()  in iwtopo_test.cpp

Solid Creation by Topology Tables

This tutorial shows the software necessary to create a Cube using the topology tables of the IwBrepData object. The IwBrepData object is the primary intermediate structure for input and output of topological objects (Trimmed Surfaces, Solids, Open Shells, Non-Manifold Models, etc.). You can read IwBrepData and write IwBrepData to and from ASCII files. The IwBrepData object is used as the intermediate structure for IGES reading of solids. Now to our example. Below is the code utilized to generate a Cube using the topology tables and an image showing the corresponding faces, edges, vertices, and edgeuses.

See Source code for MakeBox() in:iwtopo_test.cpp

Surface Filleting

Perhaps the best way to show you how to use filleting is to walk you through the little filleting application that is in iwfillet_test.cpp.  It takes two trimmed surfaces and computes the starting points for the surface fillet solver to use in tracing out the rail curves.  It does a relatively good job of computing all possible fillets and finding good starting points by intersecting the offset surfaces to get seed points for the surface fillet solver.  It tests offsets in both directions for each surface.  In some cases there are multiple correct answers to this problem.  To further refine this function, it should take offset directions (positive or negative relative to the surface normal) for each surface.

 /***********************************************************************
PURPOSE --- This is a generic routine to test Surface-Based Filleting.
    It assumes that the trimmed surfaces to be filleted are the only
    faces in their respective Brep.  It tries four combinations by
    varying the  sign of the surface offset to try to find an
    intersection in the offset trimmed surfaces.  It does a relatively
    good job of finding all possible fillets. 

USAGE NOTES ---
***********************************************************************/

IwStatus my_test_two_brep_fillet(const IwContext & crContext,
        // Creation context for the new brep that contains the results.
        IwBrep *pBrep,
        // Brep which contains a single trimmed surface (face)
        IwBrep *pBrep2,
        // Brep which contains a single trimmed surface (face)
        double dFilletRadius1,
        // Radius of the fillet brep 1 surface (signed)
        double dFilletRadius2,
        // Radius of the fillet brep 2 surface (signed)
        double dTolerance,
        // Tolerance defining
        IwBoundaryTrimmingType eTrimType,
        // Specifies what to do at the end of the surfaces in terms
        // of trimming.
        IwBrep *& rpResult,
        // The resulting fillet surface or surfaces as seperate
        // faces within theis new brep
        IwBoolean bDoGraphics)
{
    rpResult = NULL;

    // Enable editing on the two original Breps for the
    // duration of this function.
    IwTemporaryChangeValue<IwBoolean>
        sChange1(pBrep->m_bEditingEnabled,TRUE);
    IwTemporaryChangeValue<IwBoolean>
        sChange2(pBrep2->m_bEditingEnabled,TRUE);

    // For right now we assume the each Brep has only one face
    // and that is the one we use for filleting. 
    IwTArray<IwFace*> sFaces;
    pBrep->GetFaces(sFaces);
    IwFace *pF1 = sFaces[0];
    pBrep2->GetFaces(sFaces);
    IwFace *pF2 = sFaces[0];
    IwExtent2d sDomain1 = pF1->GetUVDomain();
    IwExtent2d sDomain2 = pF2->GetUVDomain();
    IwSurface *pSur1 = pF1->GetSurface();
    IwSurface *pSur2 = pF2->GetSurface();
   
    // Do something real simple here to get orientations - just
    // use center of surfaces and normal vectors to take a guess
    // at which direction the offset should be made.
    // This should give us a good starting point for choosing the
    // correct orientation the first time for many of the cases.
    IwPoint3d sP1, sP2;
    // Don't put the guesses exactly on the center because of the
    // way things tend to line up.
    IwPoint2d sGuess1 = sDomain1.Evaluate(0.5001,0.4999);
    IwPoint2d sGuess2 = sDomain2.Evaluate(0.4999,0.5001);
    SER(pSur1->EvaluatePoint(sGuess1,sP1));
    SER(pSur2->EvaluatePoint(sGuess2,sP2));
    IwVector3d sNorm1, sNorm2;
    SER(pSur1->EvaluateNormal(sGuess1,TRUE,TRUE,sNorm1));
    SER(pSur2->EvaluateNormal(sGuess2,TRUE,TRUE,sNorm2));
   
   
    // If the normal of the center is in the same direction
    // as the vector to the other surface the orientation is the same.
    IwVector3d sV1 = sP2 - sP1;
    IwBoolean bOr1 = TRUE;
    if (sV1.Dot(sNorm1) < 0.0) { bOr1 = FALSE; }
    IwBoolean bOr2 = TRUE;
    sV1 = - sV1;
    if (sV1.Dot(sNorm2) < 0.0) { bOr2 = FALSE; }

    // If the initial guess does not yeild a good result try swapping
    // the orientations and keep going until we have tried all four
    // combinations of surface offsets.  If we don't get any answers
    // after all four tries then there is not a valid fillet between
    // the two trimmed surfaces of the given radius. 
   
    // This loop tries both side of surface 1 offsets
    for (ULONG i=0; i<2; i++) {

        if (i==1) bOr1 = !bOr1;
        double dRadius1 = dFilletRadius1;
        if (!bOr1) dRadius1 = - dRadius1;

        // This loop tries both sides of surface 2 offsets
        for (ULONG j=0; j<2; j++) {
            IwBoolean bOr2Tmp = bOr2;
            if (j==1) bOr2Tmp = !bOr2;

            double dRadius2 = dFilletRadius2;
            if (!bOr2Tmp) dRadius2 = - dRadius2;
            if (my_test_surface_fillet(crContext,pF1,pF2,dRadius1,
                dRadius2,dTolerance,eTrimType,FALSE,2,0.1,FALSE,FALSE,rpResult) == IW_SUCCESS) {
                if (rpResult) return IW_SUCCESS;
            }
        }
    }

    return IW_SUCCESS;
}
As you can see there are various tools that need to be put together to make to make surface filleting work. Here is an outline of the process:
  1. Create a fillet executive object
  2. For each surface/surface pair to fillet
    • Create surface/surface fillet solver
    • Create fillet cross section curve generator
    • Attach cross section generator to the fillet solver
    • Set the trim type of the fillet solver
    • Attach the fillet solver to the fillet executive
  3. Test the resulting Brep to see if any surfaces are produced

Legal Stuff

All of the software and documentation received with this release is copyrighted by Solid Modeling Solutions, Inc. You may not distribute source code or documentation for this software outside of the company and the site which owns the license. The standard license agreement allows you to freely distribute object code in any application which does not contain a programmatic interface. All software and documentation is considered proprietary information and the intellectual property of Solid Modeling Solutions, Inc. This document contains trade secret information which is deemed proprietary.

Copyright 1998-2010 Solid Modeling Solutions All rights reserved.
Information in this document is subject to change without notice.