mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-01 19:46:08 +08:00
651 lines
23 KiB
C++
651 lines
23 KiB
C++
/* $NoKeywords: $ */
|
|
/*
|
|
//
|
|
// Copyright (c) 1993-2011 Robert McNeel & Associates. All rights reserved.
|
|
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
|
|
// McNeel & Associates.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
|
|
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
|
|
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
|
|
//
|
|
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
*/
|
|
|
|
#include "../opennurbs_public_examples.h"
|
|
|
|
// This example demonstrates two things:
|
|
//
|
|
// 1) How to dig through a ON_Brep face and get at the surface
|
|
// and trimming information. See TraverseBrepFace() for
|
|
// details.
|
|
//
|
|
// 2) How to write an OpenNURBS B-rep. See MakeTwistedCube() for details.
|
|
|
|
void TraverseBrepFace(
|
|
const ON_Brep& brep,
|
|
int fi, // brep face index
|
|
ON_TextLog& error_log
|
|
)
|
|
{
|
|
if ( fi < 0 || fi >= brep.m_F.Count() )
|
|
{
|
|
error_log.Print("Invalid face index\n");
|
|
return;
|
|
}
|
|
|
|
const ON_BrepFace& face = brep.m_F[fi];
|
|
|
|
// pSrf = underlying untrimmed surface
|
|
const ON_Surface* pSrf = NULL;
|
|
if ( face.m_si < 0 || face.m_si >= brep.m_S.Count() )
|
|
error_log.Print("ERROR: invalid brep.m_F[%d].m_si\n", fi );
|
|
else {
|
|
pSrf = brep.m_S[face.m_si];
|
|
if ( !pSrf )
|
|
error_log.Print("ERROR: invalid brep.m_S[%d] is NULL\n", face.m_si );
|
|
}
|
|
|
|
// The face is trimmed with one or more trimming loops.
|
|
//
|
|
// All the 2d trimming curves are oriented so that the
|
|
// active region of the trimmed surface lies to the left
|
|
// of the 2d trimming curve.
|
|
//
|
|
// If face.m_bRev is true, the orientations of the face in
|
|
// the b-rep is opposited the natural parameteric orientation
|
|
// of the surface.
|
|
|
|
// loop_count = number of trimming loops on this face (>=1)
|
|
const int loop_count = face.m_li.Count();
|
|
|
|
int fli; // face's loop index
|
|
for ( fli = 0; fli < loop_count; fli++ ) {
|
|
const int li = face.m_li[fli]; // li = brep loop index
|
|
const ON_BrepLoop& loop = brep.m_L[li];
|
|
|
|
// loop_edge_count = number of trimming edges in this loop
|
|
const int loop_trim_count = loop.m_ti.Count();
|
|
|
|
int lti; // loop's trim index
|
|
for ( lti = 0; lti < loop_trim_count; lti++ ) {
|
|
const int ti = loop.m_ti[lti]; // ti = brep trim index
|
|
const ON_BrepTrim& trim = brep.m_T[ti];
|
|
|
|
//////////////////////////////////////////////////////
|
|
// 2d trimming information
|
|
//
|
|
// Each trim has a 2d parameter space curve.
|
|
const ON_Curve* p2dCurve = NULL;
|
|
const int c2i = trim.m_c2i; // c2i = brep 2d curve index
|
|
if ( c2i < 0 || c2i >= brep.m_C2.Count() ) {
|
|
error_log.Print("ERROR: invalid brep.m_T[%d].m_c2i\n", ti );
|
|
}
|
|
else {
|
|
p2dCurve = brep.m_C2[c2i];
|
|
if ( !p2dCurve )
|
|
error_log.Print("ERROR: invalid brep.m_C2[%d] is NULL\n", c2i );
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
// topology and 3d geometry information
|
|
//
|
|
|
|
// Trim starts at v0 and ends at v1. When the trim
|
|
// is a loop or on a singular surface side, v0i and v1i
|
|
// will be equal.
|
|
//const int v0i = trim.m_vi[0]; // v0i = brep vertex index
|
|
//const int v1i = trim.m_vi[1]; // v1i = brep vertex index
|
|
//const ON_BrepVertex& v0 = brep.m_V[v0i];
|
|
//const ON_BrepVertex& v1 = brep.m_V[v1i];
|
|
// The vX.m_ei[] array contains the brep.m_E[] indices of
|
|
// the edges that begin or end at vX.
|
|
|
|
const int ei = trim.m_ei;
|
|
if ( ei == -1 ) {
|
|
// This trim lies on a portion of a singular surface side.
|
|
// The vertex indices are still valid and will be equal.
|
|
}
|
|
else {
|
|
// If trim.m_bRev3d is false, the orientations of the 3d edge
|
|
// and the 3d curve obtained by composing the surface and 2d
|
|
// curve agree.
|
|
//
|
|
// If trim.m_bRev3d is true, the orientations of the 3d edge
|
|
// and the 3d curve obtained by composing the surface and 2d
|
|
// curve are opposite.
|
|
const ON_BrepEdge& edge = brep.m_E[ei];
|
|
const int c3i = edge.m_c3i;
|
|
const ON_Curve* p3dCurve = NULL;
|
|
|
|
if ( c3i < 0 || c3i >= brep.m_C3.Count() ) {
|
|
error_log.Print("ERROR: invalid brep.m_E[%d].m_c3i\n", ei );
|
|
}
|
|
else {
|
|
p3dCurve = brep.m_C3[c3i];
|
|
if ( !p3dCurve )
|
|
error_log.Print("ERROR: invalid brep.m_C3[%d] is NULL\n", c3i );
|
|
}
|
|
|
|
// The edge.m_ti[] array contains the brep.m_T[] indices
|
|
// for the other trims that are joined to this edge.
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// symbolic vertex index constants to make code more readable
|
|
static const int
|
|
A = 0,
|
|
B = 1,
|
|
C = 2,
|
|
D = 3,
|
|
E = 4,
|
|
F = 5,
|
|
G = 6,
|
|
H = 7;
|
|
|
|
// symbolic edge index constants to make code more readable
|
|
static const int
|
|
AB = 0,
|
|
BC = 1,
|
|
CD = 2,
|
|
AD = 3,
|
|
EF = 4,
|
|
FG = 5,
|
|
GH = 6,
|
|
EH = 7,
|
|
AE = 8,
|
|
BF = 9,
|
|
CG = 10,
|
|
DH = 11;
|
|
|
|
// symbolic face index constants to make code more readable
|
|
static const int
|
|
ABCD = 0,
|
|
BCGF = 1,
|
|
CDHG = 2,
|
|
ADHE = 3,
|
|
ABFE = 4,
|
|
EFGH = 5;
|
|
|
|
static ON_Curve* TwistedCubeTrimmingCurve(
|
|
const ON_Surface& s,
|
|
int side // 0 = SW to SE
|
|
// 1 = SE to NE
|
|
// 2 = NE to NW
|
|
// 3 = NW to SW
|
|
)
|
|
{
|
|
// A trimming curve is a 2d curve whose image lies in the surface's domain.
|
|
// The "active" portion of the surface is to the left of the trimming curve.
|
|
// An outer trimming loop consists of a simple closed curve running
|
|
// counter-clockwise around the region it trims.
|
|
|
|
ON_2dPoint from, to;
|
|
double u0, u1, v0, v1;
|
|
|
|
s.GetDomain( 0, &u0, &u1 );
|
|
s.GetDomain( 1, &v0, &v1 );
|
|
|
|
switch ( side ) {
|
|
case 0: // SW to SE
|
|
from.x = u0; from.y = v0;
|
|
to.x = u1; to.y = v0;
|
|
break;
|
|
case 1: // SE to NE
|
|
from.x = u1; from.y = v0;
|
|
to.x = u1; to.y = v1;
|
|
break;
|
|
case 2: // NE to NW
|
|
from.x = u1; from.y = v1;
|
|
to.x = u0; to.y = v1;
|
|
break;
|
|
case 3: // NW to SW
|
|
from.x = u0; from.y = v1;
|
|
to.x = u0; to.y = v0;
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
ON_Curve* c2d = new ON_LineCurve( from, to );
|
|
c2d->SetDomain(0.0,1.0);
|
|
|
|
return c2d;
|
|
}
|
|
|
|
|
|
static ON_Curve* TwistedCubeEdgeCurve( const ON_3dPoint& from, const ON_3dPoint& to )
|
|
{
|
|
// creates a 3d line segment to be used as a 3d curve in a ON_Brep
|
|
ON_Curve* c3d = new ON_LineCurve( from, to );
|
|
c3d->SetDomain( 0.0, 1.0 );
|
|
return c3d;
|
|
}
|
|
|
|
static ON_Surface* TwistedCubeSideSurface(
|
|
const ON_3dPoint& SW, const ON_3dPoint& SE,
|
|
const ON_3dPoint& NE, const ON_3dPoint& NW
|
|
)
|
|
{
|
|
ON_NurbsSurface* pNurbsSurface = new ON_NurbsSurface(
|
|
3, // dimension
|
|
false, // not rational
|
|
2, // "u" order
|
|
2, // "v" order
|
|
2, // number of control vertices in "u" dir
|
|
2 // number of control vertices in "v" dir
|
|
);
|
|
// corner CVs in counter clockwise order starting in the south west
|
|
pNurbsSurface->SetCV( 0,0, SW );
|
|
pNurbsSurface->SetCV( 1,0, SE );
|
|
pNurbsSurface->SetCV( 1,1, NE );
|
|
pNurbsSurface->SetCV( 0,1, NW );
|
|
// "u" knots
|
|
pNurbsSurface->SetKnot( 0,0, 0.0 );
|
|
pNurbsSurface->SetKnot( 0,1, 1.0 );
|
|
// "v" knots
|
|
pNurbsSurface->SetKnot( 1,0, 0.0 );
|
|
pNurbsSurface->SetKnot( 1,1, 1.0 );
|
|
|
|
return pNurbsSurface;
|
|
}
|
|
|
|
static void MakeTwistedCubeEdge( ON_Brep& brep,
|
|
int vi0, // index of start vertex
|
|
int vi1, // index of end vertex
|
|
int c3i // index of 3d curve
|
|
)
|
|
{
|
|
ON_BrepVertex& v0 = brep.m_V[vi0];
|
|
ON_BrepVertex& v1 = brep.m_V[vi1];
|
|
ON_BrepEdge& edge = brep.NewEdge(v0,v1,c3i);
|
|
edge.m_tolerance = 0.0; // this simple example is exact - for models with
|
|
// non-exact data, set tolerance as explained in
|
|
// definition of ON_BrepEdge.
|
|
}
|
|
|
|
static void MakeTwistedCubeEdges( ON_Brep& brep )
|
|
{
|
|
|
|
// In this simple example, the edge indices exactly match the 3d
|
|
// curve indices. In general,the correspondence between edge and
|
|
// curve indices can be arbitrary. It is permitted for multiple
|
|
// edges to use different portions of the same 3d curve. The
|
|
// orientation of the edge always agrees with the natural
|
|
// parametric orientation of the curve.
|
|
|
|
// edge that runs from A to B
|
|
MakeTwistedCubeEdge( brep, A, B, AB );
|
|
|
|
// edge that runs from B to C
|
|
MakeTwistedCubeEdge( brep, B, C, BC );
|
|
|
|
// edge that runs from C to D
|
|
MakeTwistedCubeEdge( brep, C, D, CD );
|
|
|
|
// edge that runs from A to D
|
|
MakeTwistedCubeEdge( brep, A, D, AD );
|
|
|
|
// edge that runs from E to F
|
|
MakeTwistedCubeEdge( brep, E, F, EF );
|
|
|
|
// edge that runs from F to G
|
|
MakeTwistedCubeEdge( brep, F, G, FG );
|
|
|
|
// edge that runs from G to H
|
|
MakeTwistedCubeEdge( brep, G, H, GH );
|
|
|
|
// edge that runs from E to H
|
|
MakeTwistedCubeEdge( brep, E, H, EH );
|
|
|
|
// edge that runs from A to E
|
|
MakeTwistedCubeEdge( brep, A, E, AE );
|
|
|
|
// edge that runs from B to F
|
|
MakeTwistedCubeEdge( brep, B, F, BF );
|
|
|
|
// edge that runs from C to G
|
|
MakeTwistedCubeEdge( brep, C, G, CG );
|
|
|
|
// edge that runs from D to H
|
|
MakeTwistedCubeEdge( brep, D, H, DH );
|
|
}
|
|
|
|
static int MakeTwistedCubeTrimmingLoop( ON_Brep& brep, // returns index of loop
|
|
ON_BrepFace& face, // face loop is on
|
|
//int vSWi, int vSEi, int vNEi, int vNWi, // Indices of corner vertices listed in SW,SE,NW,NE order
|
|
int eSi, // index of edge on south side of surface
|
|
int eS_dir, // orientation of edge with respect to surface trim
|
|
int eEi, // index of edge on south side of surface
|
|
int eE_dir, // orientation of edge with respect to surface trim
|
|
int eNi, // index of edge on south side of surface
|
|
int eN_dir, // orientation of edge with respect to surface trim
|
|
int eWi, // index of edge on south side of surface
|
|
int eW_dir // orientation of edge with respect to surface trim
|
|
)
|
|
{
|
|
const ON_Surface& srf = *brep.m_S[face.m_si];
|
|
|
|
ON_BrepLoop& loop = brep.NewLoop( ON_BrepLoop::outer, face );
|
|
|
|
// Create trimming curves running counter clockwise around the surface's domain.
|
|
// Start at the south side
|
|
ON_Curve* c2;
|
|
int c2i, ei=0, bRev3d=0;
|
|
ON_2dPoint q;
|
|
ON_Surface::ISO iso = ON_Surface::not_iso;
|
|
|
|
for ( int side = 0; side < 4; side++ ) {
|
|
// side: 0=south, 1=east, 2=north, 3=west
|
|
|
|
c2 = TwistedCubeTrimmingCurve( srf, side );
|
|
c2i = brep.m_C2.Count();
|
|
brep.m_C2.Append(c2);
|
|
|
|
switch ( side ) {
|
|
case 0: // south
|
|
ei = eSi;
|
|
bRev3d = (eS_dir == -1);
|
|
iso = ON_Surface::S_iso;
|
|
break;
|
|
case 1: // east
|
|
ei = eEi;
|
|
bRev3d = (eE_dir == -1);
|
|
iso = ON_Surface::E_iso;
|
|
break;
|
|
case 2: // north
|
|
ei = eNi;
|
|
bRev3d = (eN_dir == -1);
|
|
iso = ON_Surface::N_iso;
|
|
break;
|
|
case 3: // west
|
|
ei = eWi;
|
|
bRev3d = (eW_dir == -1);
|
|
iso = ON_Surface::W_iso;
|
|
break;
|
|
}
|
|
|
|
ON_BrepTrim& trim = brep.NewTrim( brep.m_E[ei], bRev3d, loop, c2i );
|
|
q = c2->PointAtStart();
|
|
//trim.m_P[0] = srf.PointAt( q.x, q.y );
|
|
q = c2->PointAtEnd();
|
|
//trim.m_P[1] = srf.PointAt( q.x, q.y );
|
|
trim.m_iso = iso;
|
|
trim.m_type = ON_BrepTrim::mated; // This b-rep is closed, so all trims
|
|
// have mates.
|
|
trim.m_tolerance[0] = 0.0; // This simple example is exact - for models with
|
|
trim.m_tolerance[1] = 0.0; // non-exact data, set tolerance as explained in
|
|
// definition of ON_BrepTrim.
|
|
}
|
|
|
|
return loop.m_loop_index;
|
|
}
|
|
|
|
static void MakeTwistedCubeFace( ON_Brep& brep,
|
|
int si, // index of 3d surface
|
|
int s_dir, // orientation of surface with respect to brep
|
|
//int vSWi, int vSEi, int vNEi, int vNWi, // Indices of corner vertices listed in SW,SE,NW,NE order
|
|
int eSi, // index of edge on south side of surface
|
|
int eS_dir, // orientation of edge with respect to surface trim
|
|
int eEi, // index of edge on south side of surface
|
|
int eE_dir, // orientation of edge with respect to surface trim
|
|
int eNi, // index of edge on south side of surface
|
|
int eN_dir, // orientation of edge with respect to surface trim
|
|
int eWi, // index of edge on south side of surface
|
|
int eW_dir // orientation of edge with respect to surface trim
|
|
)
|
|
{
|
|
ON_BrepFace& face = brep.NewFace(si);
|
|
|
|
MakeTwistedCubeTrimmingLoop( brep, face,
|
|
//vSWi, vSEi, vNEi, vNWi,
|
|
eSi, eS_dir,
|
|
eEi, eE_dir,
|
|
eNi, eN_dir,
|
|
eWi, eW_dir
|
|
);
|
|
|
|
face.m_bRev = (s_dir == -1);
|
|
}
|
|
|
|
static void MakeTwistedCubeFaces( ON_Brep& brep )
|
|
{
|
|
|
|
MakeTwistedCubeFace( brep,
|
|
ABCD, // Index of surface ABCD
|
|
+1, // orientation of surface with respect to brep
|
|
//A, B, C, D, // Indices of vertices listed in SW,SE,NW,NE order
|
|
AB,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (AB)
|
|
BC,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (BC)
|
|
CD,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve (CD)
|
|
AD,-1 // South side edge and its orientation with respect to
|
|
// to the trimming curve (AD)
|
|
);
|
|
|
|
MakeTwistedCubeFace( brep,
|
|
BCGF, // Index of surface BCGF
|
|
-1, // orientation of surface with respect to brep
|
|
//B, C, G, F, // Indices of vertices listed in SW,SE,NW,NE order
|
|
BC,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (BC)
|
|
CG,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (CG)
|
|
FG,-1, // South side edge and its orientation with respect to
|
|
// to the trimming curve (FG)
|
|
BF,-1 // South side edge and its orientation with respect to
|
|
// to the trimming curve (BF)
|
|
);
|
|
|
|
MakeTwistedCubeFace( brep,
|
|
CDHG, // Index of surface CDHG
|
|
-1, // orientation of surface with respect to brep
|
|
//C, D, H, G, // Indices of vertices listed in SW,SE,NW,NE order
|
|
CD,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (CD)
|
|
DH,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (DH)
|
|
GH,-1, // South side edge and its orientation with respect to
|
|
// to the trimming curve (GH)
|
|
CG,-1 // South side edge and its orientation with respect to
|
|
// to the trimming curve (CG)
|
|
);
|
|
|
|
MakeTwistedCubeFace( brep,
|
|
ADHE, // Index of surface ADHE
|
|
+1, // orientation of surface with respect to brep
|
|
//A, D, H, E, // Indices of vertices listed in SW,SE,NW,NE order
|
|
AD,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (AD)
|
|
DH,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (DH)
|
|
EH,-1, // South side edge and its orientation with respect to
|
|
// to the trimming curve (EH)
|
|
AE,-1 // South side edge and its orientation with respect to
|
|
// to the trimming curve (AE)
|
|
);
|
|
|
|
MakeTwistedCubeFace( brep,
|
|
ABFE, // Index of surface ABFE
|
|
-1, // orientation of surface with respect to brep
|
|
//A, B, F, E, // Indices of vertices listed in SW,SE,NW,NE order
|
|
AB,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (AB)
|
|
BF,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (BF)
|
|
EF,-1, // South side edge and its orientation with respect to
|
|
// to the trimming curve (EF)
|
|
AE,-1 // South side edge and its orientation with respect to
|
|
// to the trimming curve (AE)
|
|
);
|
|
|
|
MakeTwistedCubeFace( brep,
|
|
EFGH, // Index of surface EFGH
|
|
-1, // orientation of surface with respect to brep
|
|
//E, F, G, H, // Indices of vertices listed in SW,SE,NW,NE order
|
|
EF,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (EF)
|
|
FG,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve. (FG)
|
|
GH,+1, // South side edge and its orientation with respect to
|
|
// to the trimming curve (GH)
|
|
EH,-1 // South side edge and its orientation with respect to
|
|
// to the trimming curve (EH)
|
|
);
|
|
}
|
|
|
|
|
|
static ON_Brep* MakeTwistedCube( ON_TextLog& error_log )
|
|
{
|
|
// This example demonstrates how to construct a ON_Brep
|
|
// with the topology shown below.
|
|
//
|
|
//
|
|
// H-------e6-------G
|
|
// / /|
|
|
// / | / |
|
|
// / e7 / e5
|
|
// / | / |
|
|
// / e10 |
|
|
// / | / |
|
|
// e11 E- - e4- -/- - - F
|
|
// / / /
|
|
// / / / /
|
|
// D---------e2-----C e9
|
|
// | / | /
|
|
// | e8 | /
|
|
// e3 / e1 /
|
|
// | | /
|
|
// | / | /
|
|
// | |/
|
|
// A-------e0-------B
|
|
//
|
|
//
|
|
|
|
ON_3dPoint point[8] = {
|
|
ON_3dPoint( 0.0, 0.0, 0.0 ), // point A = geometry for vertex 0
|
|
ON_3dPoint( 10.0, 0.0, 0.0 ), // point B = geometry for vertex 1
|
|
ON_3dPoint( 10.0, 8.0, -1.0 ), // point C = geometry for vertex 2
|
|
ON_3dPoint( 0.0, 6.0, 0.0 ), // point D = geometry for vertex 3
|
|
ON_3dPoint( 1.0, 2.0, 11.0 ), // point E = geometry for vertex 4
|
|
ON_3dPoint( 10.0, 0.0, 12.0 ), // point F = geometry for vertex 5
|
|
ON_3dPoint( 10.0, 7.0, 13.0 ), // point G = geometry for vertex 6
|
|
ON_3dPoint( 0.0, 6.0, 12.0 ) // point H = geometry for vertex 7
|
|
};
|
|
|
|
ON_Brep* brep = new ON_Brep();
|
|
|
|
// create eight vertices located at the eight points
|
|
int vi;
|
|
for ( vi = 0; vi < 8; vi++ ) {
|
|
ON_BrepVertex& v = brep->NewVertex(point[vi]);
|
|
v.m_tolerance = 0.0; // this simple example is exact - for models with
|
|
// non-exact data, set tolerance as explained in
|
|
// definition of ON_BrepVertex.
|
|
}
|
|
|
|
// Create 3d curve geometry - the orientations are arbitrarily chosen
|
|
// so that the end vertices are in alphabetical order.
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[A], point[B] ) ); // line AB
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[B], point[C] ) ); // line BC
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[C], point[D] ) ); // line CD
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[A], point[D] ) ); // line AD
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[E], point[F] ) ); // line EF
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[F], point[G] ) ); // line FG
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[G], point[H] ) ); // line GH
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[E], point[H] ) ); // line EH
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[A], point[E] ) ); // line AE
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[B], point[F] ) ); // line BF
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[C], point[G] ) ); // line CG
|
|
brep->m_C3.Append( TwistedCubeEdgeCurve( point[D], point[H] ) ); // line DH
|
|
|
|
// Create the 12 edges that connect the corners of the cube.
|
|
MakeTwistedCubeEdges( *brep );
|
|
|
|
// Create 3d surface geometry - the orientations are arbitrarily chosen so
|
|
// that some normals point into the cube and others point out of the cube.
|
|
brep->m_S.Append( TwistedCubeSideSurface( point[A], point[B], point[C], point[D] ) ); // ABCD
|
|
brep->m_S.Append( TwistedCubeSideSurface( point[B], point[C], point[G], point[F] ) ); // BCGF
|
|
brep->m_S.Append( TwistedCubeSideSurface( point[C], point[D], point[H], point[G] ) ); // CDHG
|
|
brep->m_S.Append( TwistedCubeSideSurface( point[A], point[D], point[H], point[E] ) ); // ADHE
|
|
brep->m_S.Append( TwistedCubeSideSurface( point[A], point[B], point[F], point[E] ) ); // ABFE
|
|
brep->m_S.Append( TwistedCubeSideSurface( point[E], point[F], point[G], point[H] ) ); // EFGH
|
|
|
|
|
|
// Create the CRhinoBrepFaces
|
|
MakeTwistedCubeFaces( *brep );
|
|
|
|
if ( !brep->IsValid() )
|
|
{
|
|
error_log.Print("Twisted cube b-rep is not valid.\n");
|
|
delete brep;
|
|
brep = NULL;
|
|
}
|
|
|
|
//ON_BOOL32 bIsManifold;
|
|
//ON_BOOL32 bHasBoundary;
|
|
//ON_BOOL32 b = brep->IsManifold( &bIsManifold,&bHasBoundary );
|
|
|
|
return brep;
|
|
}
|
|
|
|
//int main( int argc, const char *argv[] )
|
|
int main()
|
|
{
|
|
ON::Begin();
|
|
|
|
ON_TextLog error_log;
|
|
|
|
// Before working through this example, you should understand
|
|
// the example_write.cpp example.
|
|
|
|
ON_Brep* brep = MakeTwistedCube(error_log);
|
|
if ( !brep )
|
|
return 1;
|
|
|
|
ONX_Model model;
|
|
|
|
// OPTIONAL - change values from defaults
|
|
model.m_properties.m_Notes.m_notes = "File created by OpenNURBS example_brep.cpp";
|
|
model.m_properties.m_Notes.m_bVisible = true;
|
|
|
|
model.m_properties.m_Application.m_application_name
|
|
= "OpenNURBS example_brep.cpp";
|
|
model.m_properties.m_Application.m_application_URL
|
|
= "http://www.opennurbs.org";
|
|
model.m_properties.m_Application.m_application_details
|
|
= "OpenNURBS example showing how to create and write a simple b-rep";
|
|
|
|
model.AddDefaultLayer(L"brep", ON_Color::UnsetColor);
|
|
|
|
ON_3dmObjectAttributes attributes;
|
|
attributes.m_name = "Twisted b-rep";
|
|
bool bResolveIdAndNameConflicts = true;
|
|
|
|
model.AddModelGeometryComponent(brep, &attributes, bResolveIdAndNameConflicts);
|
|
|
|
|
|
const int version = 0; // version will be ON_BinaryArchive::CurrentArchiveVersion()
|
|
const char* filename = "my_brep.3dm";
|
|
model.m_sStartSectionComments = __FILE__ " example_brep.cpp " __DATE__;
|
|
bool rc = model.Write( filename,
|
|
version,
|
|
&error_log
|
|
);
|
|
if (rc)
|
|
printf("Wrote %s.\n",filename);
|
|
else
|
|
printf("Errors writing %s.\n",filename);
|
|
|
|
ON::End();
|
|
|
|
return 0;
|
|
}
|