Add Twisted Cube
Demonstrates how to construct a twisted cube object from an array of points and a list of curves.
partial class Examples
{
// Symbolic vertex index constants to make code more readable
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
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
const int ABCD = 0, BCGF = 1, CDHG = 2, ADHE = 3, ABFE = 4, EFGH = 5;
public static Rhino.Commands.Result AddTwistedCube(Rhino.RhinoDoc doc)
{
Point3d[] points = new Point3d[8];
points[0] = new Point3d(0.0, 0.0, 0.0); // point A = geometry for vertex 0
points[1] = new Point3d(10.0, 0.0, 0.0); // point B = geometry for vertex 1
points[2] = new Point3d(10.0, 8.0, -1.0); // point C = geometry for vertex 2
points[3] = new Point3d(0.0, 6.0, 0.0); // point D = geometry for vertex 3
points[4] = new Point3d(1.0, 2.0, 11.0); // point E = geometry for vertex 4
points[5] = new Point3d(10.0, 0.0, 12.0); // point F = geometry for vertex 5
points[6] = new Point3d(10.0, 7.0, 13.0); // point G = geometry for vertex 6
points[7] = new Point3d(0.0, 6.0, 12.0); // point H = geometry for vertex 7
Brep brep = new Brep();
// Create eight vertices located at the eight points
for (int vi = 0; vi < 8; vi++)
brep.Vertices.Add(points[vi], 0.0);
// Create 3d curve geometry - the orientations are arbitrarily chosen
// so that the end vertices are in alphabetical order.
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[B])); // line AB
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[B], points[C])); // line BC
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[C], points[D])); // line CD
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[D])); // line AD
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[E], points[F])); // line EF
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[F], points[G])); // line FG
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[G], points[H])); // line GH
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[E], points[H])); // line EH
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[A], points[E])); // line AE
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[B], points[F])); // line BF
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[C], points[G])); // line CG
brep.Curves3D.Add(TwistedCubeEdgeCurve(points[D], points[H])); // line DH
// Create the 12 edges that connect the corners of the cube.
MakeTwistedCubeEdges(ref 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.AddSurface(TwistedCubeSideSurface(points[A], points[B], points[C], points[D])); // ABCD
brep.AddSurface(TwistedCubeSideSurface(points[B], points[C], points[G], points[F])); // BCGF
brep.AddSurface(TwistedCubeSideSurface(points[C], points[D], points[H], points[G])); // CDHG
brep.AddSurface(TwistedCubeSideSurface(points[A], points[D], points[H], points[E])); // ADHE
brep.AddSurface(TwistedCubeSideSurface(points[A], points[B], points[F], points[E])); // ABFE
brep.AddSurface(TwistedCubeSideSurface(points[E], points[F], points[G], points[H])); // EFGH
// Create the CRhinoBrepFaces
MakeTwistedCubeFaces(ref brep);
if (brep.IsValid)
{
doc.Objects.AddBrep(brep);
doc.Views.Redraw();
return Rhino.Commands.Result.Success;
}
return Rhino.Commands.Result.Failure;
}
static Curve TwistedCubeEdgeCurve(Point3d from, Point3d to)
{
// Create a 3d line segment to be used as a 3d curve in a Brep
return new LineCurve(from, to) { Domain = new Interval(0, 1) };
}
static void MakeTwistedCubeEdges(ref 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.
brep.Edges.Add(A, B, AB, 0); // Edge that runs from A to B
brep.Edges.Add(B, C, BC, 0); // Edge that runs from B to C
brep.Edges.Add(C, D, CD, 0); // Edge that runs from C to D
brep.Edges.Add(A, D, AD, 0); // Edge that runs from A to D
brep.Edges.Add(E, F, EF, 0); // Edge that runs from E to F
brep.Edges.Add(F, G, FG, 0); // Edge that runs from F to G
brep.Edges.Add(G, H, GH, 0); // Edge that runs from G to H
brep.Edges.Add(E, H, EH, 0); // Edge that runs from E to H
brep.Edges.Add(A, E, AE, 0); // Edge that runs from A to E
brep.Edges.Add(B, F, BF, 0); // Edge that runs from B to F
brep.Edges.Add(C, G, CG, 0); // Edge that runs from C to G
brep.Edges.Add(D, H, DH, 0); // Edge that runs from D to H
}
static Surface TwistedCubeSideSurface(Point3d southwest, Point3d southeast, Point3d northeast, Point3d northwest)
{
var ns = NurbsSurface.Create(3, false, 2, 2, 2, 2);
// Corner CVs in counter clockwise order starting in the south west
ns.Points.SetControlPoint(0, 0, southwest);
ns.Points.SetControlPoint(1, 0, southeast);
ns.Points.SetControlPoint(1, 1, northeast);
ns.Points.SetControlPoint(0, 1, northwest);
// "u" knots
ns.KnotsU[0] = 0.0;
ns.KnotsU[1] = 1.0;
// "v" knots
ns.KnotsV[0] = 0;
ns.KnotsV[1] = 1;
return ns;
}
static void MakeTwistedCubeFaces(ref Brep brep)
{
MakeTwistedCubeFace(ref brep,
ABCD, // Index of surface ABCD
+1, // 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(ref brep,
BCGF, // Index of surface BCGF
-1, // 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(ref brep,
CDHG, // Index of surface CDHG
-1, // 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(ref brep,
ADHE, // Index of surface ADHE
+1, // 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(ref brep,
ABFE, // Index of surface ABFE
-1, // 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(ref brep,
EFGH, // Index of surface EFGH
-1, // 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 void MakeTwistedCubeFace( ref Brep brep, int surfaceIndex,
int s_dir, // Indices of corner vertices listed in SW, SE, NW, NE order
int southEdgeIndex,
int eS_dir, // orientation of edge with respect to surface trim
int eastEdgeIndex,
int eE_dir, // orientation of edge with respect to surface trim
int northEdgeIndex,
int eN_dir, // orientation of edge with respect to surface trim
int westEdgeIndex,
int eW_dir // orientation of edge with respect to surface trim
)
{
var face = brep.Faces.Add(surfaceIndex);
MakeTwistedCubeTrimmingLoop(
ref brep,
ref face,
southEdgeIndex, eS_dir,
eastEdgeIndex, eE_dir,
northEdgeIndex, eN_dir,
westEdgeIndex, eW_dir
);
face.OrientationIsReversed = (s_dir == -1);
}
static void MakeTwistedCubeTrimmingLoop( ref Brep brep, ref BrepFace face, // 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
)
{
Surface srf = brep.Surfaces[face.SurfaceIndex];
var loop = brep.Loops.Add(BrepLoopType.Outer, face);
// Create trimming curves running counter clockwise around the surface's domain.
// Start at the south side
// side: 0=south, 1=east, 2=north, 3=west
for (int side = 0; side < 4; side++)
{
Curve trimming_curve = TwistedCubeTrimmingCurve(srf, side);
int curve_index = brep.Curves2D.Add(trimming_curve);
int ei = 0;
bool reverse = false;
IsoStatus iso = IsoStatus.None;
switch (side)
{
case 0: // south
ei = eSi;
reverse = (eS_dir == -1);
iso = IsoStatus.South;
break;
case 1: // east
ei = eEi;
reverse = (eE_dir == -1);
iso = IsoStatus.East;
break;
case 2: // north
ei = eNi;
reverse = (eN_dir == -1);
iso = IsoStatus.North;
break;
case 3: // west
ei = eWi;
reverse = (eW_dir == -1);
iso = IsoStatus.West;
break;
}
BrepEdge edge = brep.Edges[ei];
BrepTrim trim = brep.Trims.Add(edge, reverse, loop, curve_index);
trim.IsoStatus = iso;
trim.TrimType = BrepTrimType.Mated; // This b-rep is closed, so all trims have mates.
trim.SetTolerances(0, 0); // This simple example is exact - for models with
// non-exact data, set tolerance as explained in
// definition of BrepTrim.
}
}
static Curve TwistedCubeTrimmingCurve(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.
var u_domain = s.Domain(0);
var v_domain = s.Domain(1);
double u0 = u_domain[0];
double u1 = u_domain[1];
double v0 = v_domain[0];
double v1 = v_domain[1];
Point2d from;
Point2d to;
switch (side)
{
case 0: // SW to SE
from = new Point2d(u0, v0);
to = new Point2d(u1, v0);
break;
case 1: // SE to NE
from = new Point2d(u1, v0);
to = new Point2d(u1, v1);
break;
case 2: // NE to NW
from = new Point2d(u1, v1);
to = new Point2d(u0, v1);
break;
case 3: // NW to SW
from = new Point2d(u0, v1);
to = new Point2d(u0, v0);
break;
default:
return null;
}
return new LineCurve(from, to) { Domain = new Interval(0, 1) };
}
}
' No VB.NET sample available
# No Python sample available