2013-07-28 22:08:34 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Export a STEP file describing our ratpoly shell.
|
|
|
|
//
|
|
|
|
// Copyright 2008-2013 Jonathan Westhues.
|
|
|
|
//-----------------------------------------------------------------------------
|
2009-06-08 06:50:16 +00:00
|
|
|
#include "solvespace.h"
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void StepFileWriter::WriteHeader() {
|
2009-06-08 06:50:16 +00:00
|
|
|
fprintf(f,
|
|
|
|
"ISO-10303-21;\n"
|
|
|
|
"HEADER;\n"
|
|
|
|
"\n"
|
|
|
|
"FILE_DESCRIPTION((''), '2;1');\n"
|
|
|
|
"\n"
|
|
|
|
"FILE_NAME(\n"
|
|
|
|
" 'output_file',\n"
|
|
|
|
" '2009-06-07T17:44:47-07:00',\n"
|
|
|
|
" (''),\n"
|
|
|
|
" (''),\n"
|
|
|
|
" 'SolveSpace',\n"
|
|
|
|
" '',\n"
|
|
|
|
" ''\n"
|
|
|
|
");\n"
|
|
|
|
"\n"
|
|
|
|
"FILE_SCHEMA (('CONFIG_CONTROL_DESIGN'));\n"
|
|
|
|
"ENDSEC;\n"
|
|
|
|
"\n"
|
|
|
|
"DATA;\n"
|
|
|
|
"\n"
|
|
|
|
"/**********************************************************\n"
|
|
|
|
" * This defines the units and tolerances for the file. It\n"
|
|
|
|
" * is always the same, independent of the actual data.\n"
|
|
|
|
" **********************************************************/\n"
|
|
|
|
"#158=(\n"
|
|
|
|
"LENGTH_UNIT()\n"
|
|
|
|
"NAMED_UNIT(*)\n"
|
|
|
|
"SI_UNIT(.MILLI.,.METRE.)\n"
|
|
|
|
");\n"
|
|
|
|
"#161=(\n"
|
|
|
|
"NAMED_UNIT(*)\n"
|
|
|
|
"PLANE_ANGLE_UNIT()\n"
|
|
|
|
"SI_UNIT($,.RADIAN.)\n"
|
|
|
|
");\n"
|
|
|
|
"#166=(\n"
|
|
|
|
"NAMED_UNIT(*)\n"
|
|
|
|
"SI_UNIT($,.STERADIAN.)\n"
|
|
|
|
"SOLID_ANGLE_UNIT()\n"
|
|
|
|
");\n"
|
|
|
|
"#167=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.001),#158,\n"
|
|
|
|
"'DISTANCE_ACCURACY_VALUE',\n"
|
|
|
|
"'string');\n"
|
|
|
|
"#168=(\n"
|
|
|
|
"GEOMETRIC_REPRESENTATION_CONTEXT(3)\n"
|
|
|
|
"GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#167))\n"
|
|
|
|
"GLOBAL_UNIT_ASSIGNED_CONTEXT((#166,#161,#158))\n"
|
|
|
|
"REPRESENTATION_CONTEXT('ID1','3D')\n"
|
|
|
|
");\n"
|
|
|
|
"#169=SHAPE_REPRESENTATION('',(#170),#168);\n"
|
|
|
|
"#170=AXIS2_PLACEMENT_3D('',#173,#171,#172);\n"
|
|
|
|
"#171=DIRECTION('',(0.,0.,1.));\n"
|
|
|
|
"#172=DIRECTION('',(1.,0.,0.));\n"
|
|
|
|
"#173=CARTESIAN_POINT('',(0.,0.,0.));\n"
|
|
|
|
"\n"
|
|
|
|
);
|
2009-06-11 05:57:23 +00:00
|
|
|
|
|
|
|
// Start the ID somewhere beyond the header IDs.
|
|
|
|
id = 200;
|
2009-06-08 06:50:16 +00:00
|
|
|
}
|
2016-05-05 05:54:05 +00:00
|
|
|
void StepFileWriter::WriteProductHeader() {
|
2015-02-08 16:43:19 +00:00
|
|
|
fprintf(f,
|
|
|
|
"#175 = SHAPE_DEFINITION_REPRESENTATION(#176, #169);\n"
|
|
|
|
"#176 = PRODUCT_DEFINITION_SHAPE('Version', 'Test Part', #177);\n"
|
|
|
|
"#177 = PRODUCT_DEFINITION('Version', 'Test Part', #182, #178);\n"
|
|
|
|
"#178 = DESIGN_CONTEXT('3D Mechanical Parts', #181, 'design');\n"
|
|
|
|
"#179 = PRODUCT('1', 'Product', 'Test Part', (#180));\n"
|
|
|
|
"#180 = MECHANICAL_CONTEXT('3D Mechanical Parts', #181, 'mechanical');\n"
|
|
|
|
"#181 = APPLICATION_CONTEXT(\n"
|
|
|
|
"'configuration controlled 3d designs of mechanical parts and assemblies');\n"
|
|
|
|
"#182 = PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('Version',\n"
|
|
|
|
"'Test Part', #179, .MADE.);\n"
|
|
|
|
"\n"
|
|
|
|
);
|
|
|
|
}
|
2009-06-08 06:50:16 +00:00
|
|
|
int StepFileWriter::ExportCurve(SBezier *sb) {
|
|
|
|
int i, ret = id;
|
|
|
|
|
2009-06-09 02:04:15 +00:00
|
|
|
fprintf(f, "#%d=(\n", ret);
|
|
|
|
fprintf(f, "BOUNDED_CURVE()\n");
|
|
|
|
fprintf(f, "B_SPLINE_CURVE(%d,(", sb->deg);
|
2009-06-08 06:50:16 +00:00
|
|
|
for(i = 0; i <= sb->deg; i++) {
|
|
|
|
fprintf(f, "#%d", ret + i + 1);
|
|
|
|
if(i != sb->deg) fprintf(f, ",");
|
|
|
|
}
|
2009-06-09 02:04:15 +00:00
|
|
|
fprintf(f, "),.UNSPECIFIED.,.F.,.F.)\n");
|
|
|
|
fprintf(f, "B_SPLINE_CURVE_WITH_KNOTS((%d,%d),",
|
2009-06-08 06:50:16 +00:00
|
|
|
(sb->deg + 1), (sb-> deg + 1));
|
2009-06-09 02:04:15 +00:00
|
|
|
fprintf(f, "(0.000,1.000),.UNSPECIFIED.)\n");
|
|
|
|
fprintf(f, "CURVE()\n");
|
|
|
|
fprintf(f, "GEOMETRIC_REPRESENTATION_ITEM()\n");
|
|
|
|
fprintf(f, "RATIONAL_B_SPLINE_CURVE((");
|
|
|
|
for(i = 0; i <= sb->deg; i++) {
|
|
|
|
fprintf(f, "%.10f", sb->weight[i]);
|
|
|
|
if(i != sb->deg) fprintf(f, ",");
|
|
|
|
}
|
|
|
|
fprintf(f, "))\n");
|
|
|
|
fprintf(f, "REPRESENTATION_ITEM('')\n);\n");
|
2009-06-08 06:50:16 +00:00
|
|
|
|
|
|
|
for(i = 0; i <= sb->deg; i++) {
|
|
|
|
fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n",
|
|
|
|
id + 1 + i,
|
|
|
|
CO(sb->ctrl[i]));
|
|
|
|
}
|
|
|
|
fprintf(f, "\n");
|
|
|
|
|
|
|
|
id = ret + 1 + (sb->deg + 1);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-06-08 16:21:33 +00:00
|
|
|
int StepFileWriter::ExportCurveLoop(SBezierLoop *loop, bool inner) {
|
2016-05-18 22:51:36 +00:00
|
|
|
ssassert(loop->l.n >= 1, "Expected at least one loop");
|
2009-06-09 02:04:15 +00:00
|
|
|
|
2015-03-27 15:31:23 +00:00
|
|
|
List<int> listOfTrims = {};
|
2009-06-08 16:21:33 +00:00
|
|
|
|
2009-06-09 02:04:15 +00:00
|
|
|
SBezier *sb = &(loop->l.elem[loop->l.n - 1]);
|
|
|
|
|
|
|
|
// Generate "exactly closed" contours, with the same vertex id for the
|
|
|
|
// finish of a previous edge and the start of the next one. So we need
|
|
|
|
// the finish of the last Bezier in the loop before we start our process.
|
|
|
|
fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n",
|
|
|
|
id, CO(sb->Finish()));
|
|
|
|
fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id);
|
|
|
|
int lastFinish = id + 1, prevFinish = lastFinish;
|
|
|
|
id += 2;
|
|
|
|
|
2009-06-08 16:21:33 +00:00
|
|
|
for(sb = loop->l.First(); sb; sb = loop->l.NextAfter(sb)) {
|
|
|
|
int curveId = ExportCurve(sb);
|
|
|
|
|
2009-06-09 02:04:15 +00:00
|
|
|
int thisFinish;
|
|
|
|
if(loop->l.NextAfter(sb) != NULL) {
|
|
|
|
fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n",
|
|
|
|
id, CO(sb->Finish()));
|
|
|
|
fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id);
|
|
|
|
thisFinish = id + 1;
|
|
|
|
id += 2;
|
|
|
|
} else {
|
|
|
|
thisFinish = lastFinish;
|
|
|
|
}
|
|
|
|
|
2009-06-08 16:21:33 +00:00
|
|
|
fprintf(f, "#%d=EDGE_CURVE('',#%d,#%d,#%d,%s);\n",
|
2009-06-09 02:04:15 +00:00
|
|
|
id, prevFinish, thisFinish, curveId, ".T.");
|
2009-06-08 16:21:33 +00:00
|
|
|
fprintf(f, "#%d=ORIENTED_EDGE('',*,*,#%d,.T.);\n",
|
2009-06-09 02:04:15 +00:00
|
|
|
id+1, id);
|
2009-06-08 16:21:33 +00:00
|
|
|
|
2009-06-09 02:04:15 +00:00
|
|
|
int oe = id+1;
|
2009-06-08 16:21:33 +00:00
|
|
|
listOfTrims.Add(&oe);
|
2009-06-09 02:04:15 +00:00
|
|
|
id += 2;
|
2009-06-08 16:21:33 +00:00
|
|
|
|
2009-06-09 02:04:15 +00:00
|
|
|
prevFinish = thisFinish;
|
2009-06-08 16:21:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(f, "#%d=EDGE_LOOP('',(", id);
|
|
|
|
int *oe;
|
|
|
|
for(oe = listOfTrims.First(); oe; oe = listOfTrims.NextAfter(oe)) {
|
|
|
|
fprintf(f, "#%d", *oe);
|
|
|
|
if(listOfTrims.NextAfter(oe) != NULL) fprintf(f, ",");
|
|
|
|
}
|
|
|
|
fprintf(f, "));\n");
|
|
|
|
|
|
|
|
int fb = id + 1;
|
2015-03-29 00:30:52 +00:00
|
|
|
fprintf(f, "#%d=%s('',#%d,.T.);\n",
|
2009-06-08 16:21:33 +00:00
|
|
|
fb, inner ? "FACE_BOUND" : "FACE_OUTER_BOUND", id);
|
|
|
|
|
|
|
|
id += 2;
|
|
|
|
listOfTrims.Clear();
|
|
|
|
|
|
|
|
return fb;
|
|
|
|
}
|
|
|
|
|
2009-10-12 09:28:34 +00:00
|
|
|
void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) {
|
2009-06-08 06:50:16 +00:00
|
|
|
int i, j, srfid = id;
|
|
|
|
|
2009-10-22 17:16:20 +00:00
|
|
|
// First, we create the untrimmed surface. We always specify a rational
|
|
|
|
// B-spline surface (in fact, just a Bezier surface).
|
2009-06-09 02:04:15 +00:00
|
|
|
fprintf(f, "#%d=(\n", srfid);
|
|
|
|
fprintf(f, "BOUNDED_SURFACE()\n");
|
|
|
|
fprintf(f, "B_SPLINE_SURFACE(%d,%d,(", ss->degm, ss->degn);
|
2009-06-08 06:50:16 +00:00
|
|
|
for(i = 0; i <= ss->degm; i++) {
|
|
|
|
fprintf(f, "(");
|
|
|
|
for(j = 0; j <= ss->degn; j++) {
|
|
|
|
fprintf(f, "#%d", srfid + 1 + j + i*(ss->degn + 1));
|
|
|
|
if(j != ss->degn) fprintf(f, ",");
|
|
|
|
}
|
|
|
|
fprintf(f, ")");
|
|
|
|
if(i != ss->degm) fprintf(f, ",");
|
|
|
|
}
|
2009-06-09 02:04:15 +00:00
|
|
|
fprintf(f, "),.UNSPECIFIED.,.F.,.F.,.F.)\n");
|
|
|
|
fprintf(f, "B_SPLINE_SURFACE_WITH_KNOTS((%d,%d),(%d,%d),",
|
2009-06-08 06:50:16 +00:00
|
|
|
(ss->degm + 1), (ss->degm + 1),
|
|
|
|
(ss->degn + 1), (ss->degn + 1));
|
2009-06-09 02:04:15 +00:00
|
|
|
fprintf(f, "(0.000,1.000),(0.000,1.000),.UNSPECIFIED.)\n");
|
|
|
|
fprintf(f, "GEOMETRIC_REPRESENTATION_ITEM()\n");
|
|
|
|
fprintf(f, "RATIONAL_B_SPLINE_SURFACE((");
|
|
|
|
for(i = 0; i <= ss->degm; i++) {
|
|
|
|
fprintf(f, "(");
|
|
|
|
for(j = 0; j <= ss->degn; j++) {
|
|
|
|
fprintf(f, "%.10f", ss->weight[i][j]);
|
|
|
|
if(j != ss->degn) fprintf(f, ",");
|
|
|
|
}
|
|
|
|
fprintf(f, ")");
|
|
|
|
if(i != ss->degm) fprintf(f, ",");
|
|
|
|
}
|
|
|
|
fprintf(f, "))\n");
|
|
|
|
fprintf(f, "REPRESENTATION_ITEM('')\n");
|
|
|
|
fprintf(f, "SURFACE()\n");
|
|
|
|
fprintf(f, ");\n");
|
2009-06-08 06:50:16 +00:00
|
|
|
|
2009-10-22 17:16:20 +00:00
|
|
|
// The control points for the untrimmed surface.
|
2009-06-08 06:50:16 +00:00
|
|
|
for(i = 0; i <= ss->degm; i++) {
|
|
|
|
for(j = 0; j <= ss->degn; j++) {
|
2015-03-29 00:30:52 +00:00
|
|
|
fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n",
|
2009-06-08 06:50:16 +00:00
|
|
|
srfid + 1 + j + i*(ss->degn + 1),
|
|
|
|
CO(ss->ctrl[i][j]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fprintf(f, "\n");
|
|
|
|
|
|
|
|
id = srfid + 1 + (ss->degm + 1)*(ss->degn + 1);
|
|
|
|
|
2009-10-22 17:16:20 +00:00
|
|
|
// Now we do the trim curves. We must group each outer loop separately
|
|
|
|
// along with its inner faces, so do that now.
|
2015-03-27 15:31:23 +00:00
|
|
|
SBezierLoopSetSet sblss = {};
|
|
|
|
SPolygon spxyz = {};
|
2009-10-29 07:16:28 +00:00
|
|
|
bool allClosed;
|
|
|
|
SEdge notClosedAt;
|
|
|
|
// We specify a surface, so it doesn't check for coplanarity; and we
|
|
|
|
// don't want it to give us any open contours. The polygon and chord
|
|
|
|
// tolerance are required, because they are used to calculate the
|
|
|
|
// contour directions and determine inner vs. outer contours.
|
|
|
|
sblss.FindOuterFacesFrom(sbl, &spxyz, ss,
|
2016-01-27 04:07:54 +00:00
|
|
|
SS.ExportChordTolMm(),
|
2009-10-29 07:16:28 +00:00
|
|
|
&allClosed, ¬ClosedAt,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL);
|
2009-10-22 17:16:20 +00:00
|
|
|
|
|
|
|
// So in our list of SBezierLoopSet, each set contains at least one loop
|
|
|
|
// (the outer boundary), plus any inner loops associated with that outer
|
|
|
|
// loop.
|
|
|
|
SBezierLoopSet *sbls;
|
|
|
|
for(sbls = sblss.l.First(); sbls; sbls = sblss.l.NextAfter(sbls)) {
|
|
|
|
SBezierLoop *loop = sbls->l.First();
|
|
|
|
|
2015-03-27 15:31:23 +00:00
|
|
|
List<int> listOfLoops = {};
|
2009-10-22 17:16:20 +00:00
|
|
|
// Create the face outer boundary from the outer loop.
|
2016-05-25 12:08:19 +00:00
|
|
|
int fob = ExportCurveLoop(loop, /*inner=*/false);
|
2009-10-22 17:16:20 +00:00
|
|
|
listOfLoops.Add(&fob);
|
|
|
|
|
2015-03-29 00:30:52 +00:00
|
|
|
// And create the face inner boundaries from any inner loops that
|
2009-10-22 17:16:20 +00:00
|
|
|
// lie within this contour.
|
|
|
|
loop = sbls->l.NextAfter(loop);
|
|
|
|
for(; loop; loop = sbls->l.NextAfter(loop)) {
|
2016-05-25 12:08:19 +00:00
|
|
|
int fib = ExportCurveLoop(loop, /*inner=*/true);
|
2009-10-22 17:16:20 +00:00
|
|
|
listOfLoops.Add(&fib);
|
2009-06-08 06:50:16 +00:00
|
|
|
}
|
2009-10-22 17:16:20 +00:00
|
|
|
|
|
|
|
// And now create the face that corresponds to this outer loop
|
|
|
|
// and all of its holes.
|
|
|
|
int advFaceId = id;
|
|
|
|
fprintf(f, "#%d=ADVANCED_FACE('',(", advFaceId);
|
|
|
|
int *fb;
|
|
|
|
for(fb = listOfLoops.First(); fb; fb = listOfLoops.NextAfter(fb)) {
|
|
|
|
fprintf(f, "#%d", *fb);
|
|
|
|
if(listOfLoops.NextAfter(fb) != NULL) fprintf(f, ",");
|
2009-06-08 16:21:33 +00:00
|
|
|
}
|
2009-06-08 06:50:16 +00:00
|
|
|
|
2009-10-22 17:16:20 +00:00
|
|
|
fprintf(f, "),#%d,.T.);\n", srfid);
|
|
|
|
fprintf(f, "\n");
|
|
|
|
advancedFaces.Add(&advFaceId);
|
2009-06-08 06:50:16 +00:00
|
|
|
|
2009-10-22 17:16:20 +00:00
|
|
|
id++;
|
|
|
|
listOfLoops.Clear();
|
2009-06-08 16:21:33 +00:00
|
|
|
}
|
2009-10-22 17:16:20 +00:00
|
|
|
sblss.Clear();
|
2009-10-29 07:16:28 +00:00
|
|
|
spxyz.Clear();
|
2009-06-08 06:50:16 +00:00
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void StepFileWriter::WriteFooter() {
|
2009-06-11 05:57:23 +00:00
|
|
|
fprintf(f,
|
|
|
|
"\n"
|
|
|
|
"ENDSEC;\n"
|
|
|
|
"\n"
|
|
|
|
"END-ISO-10303-21;\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-03-11 14:43:21 +00:00
|
|
|
void StepFileWriter::ExportSurfacesTo(const Platform::Path &filename) {
|
2009-06-08 06:50:16 +00:00
|
|
|
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
2009-10-12 09:28:34 +00:00
|
|
|
SShell *shell = &(g->runningShell);
|
|
|
|
|
2018-01-03 21:10:18 +00:00
|
|
|
if(shell->surface.IsEmpty()) {
|
2009-06-08 06:50:16 +00:00
|
|
|
Error("The model does not contain any surfaces to export.%s",
|
2018-01-03 21:10:18 +00:00
|
|
|
!g->runningMesh.l.IsEmpty()
|
|
|
|
? "\n\nThe model does contain triangles from a mesh, but "
|
|
|
|
"a triangle mesh cannot be exported as a STEP file. Try "
|
|
|
|
"File -> Export Mesh... instead."
|
|
|
|
: "");
|
2009-06-08 06:50:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-03-11 14:43:21 +00:00
|
|
|
f = OpenFile(filename, "wb");
|
2009-06-08 06:50:16 +00:00
|
|
|
if(!f) {
|
2017-03-11 14:43:21 +00:00
|
|
|
Error("Couldn't write to '%s'", filename.raw.c_str());
|
2009-06-08 06:50:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
WriteHeader();
|
2015-02-08 16:43:19 +00:00
|
|
|
WriteProductHeader();
|
2009-06-08 06:50:16 +00:00
|
|
|
|
2015-03-27 15:31:23 +00:00
|
|
|
advancedFaces = {};
|
2009-06-08 06:50:16 +00:00
|
|
|
|
|
|
|
SSurface *ss;
|
|
|
|
for(ss = shell->surface.First(); ss; ss = shell->surface.NextAfter(ss)) {
|
2018-01-03 21:10:18 +00:00
|
|
|
if(ss->trim.IsEmpty())
|
|
|
|
continue;
|
2009-06-08 06:50:16 +00:00
|
|
|
|
2009-10-12 09:28:34 +00:00
|
|
|
// Get all of the loops of Beziers that trim our surface (with each
|
|
|
|
// Bezier split so that we use the section as t goes from 0 to 1), and
|
|
|
|
// the piecewise linearization of those loops in xyz space.
|
2015-03-27 15:31:23 +00:00
|
|
|
SBezierList sbl = {};
|
2009-10-12 09:28:34 +00:00
|
|
|
ss->MakeSectionEdgesInto(shell, NULL, &sbl);
|
|
|
|
|
|
|
|
// Apply the export scale factor.
|
|
|
|
ss->ScaleSelfBy(1.0/SS.exportScale);
|
|
|
|
sbl.ScaleSelfBy(1.0/SS.exportScale);
|
|
|
|
|
|
|
|
ExportSurface(ss, &sbl);
|
|
|
|
|
|
|
|
sbl.Clear();
|
2009-06-08 06:50:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(f, "#%d=CLOSED_SHELL('',(", id);
|
2009-06-08 16:21:33 +00:00
|
|
|
int *af;
|
|
|
|
for(af = advancedFaces.First(); af; af = advancedFaces.NextAfter(af)) {
|
|
|
|
fprintf(f, "#%d", *af);
|
|
|
|
if(advancedFaces.NextAfter(af) != NULL) fprintf(f, ",");
|
2009-06-08 06:50:16 +00:00
|
|
|
}
|
|
|
|
fprintf(f, "));\n");
|
2009-06-09 02:04:15 +00:00
|
|
|
fprintf(f, "#%d=MANIFOLD_SOLID_BREP('brep',#%d);\n", id+1, id);
|
2009-06-08 06:50:16 +00:00
|
|
|
fprintf(f, "#%d=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#%d,#170),#168);\n",
|
|
|
|
id+2, id+1);
|
|
|
|
fprintf(f, "#%d=SHAPE_REPRESENTATION_RELATIONSHIP($,$,#169,#%d);\n",
|
|
|
|
id+3, id+2);
|
|
|
|
|
2009-06-11 05:57:23 +00:00
|
|
|
WriteFooter();
|
2009-06-08 06:50:16 +00:00
|
|
|
|
|
|
|
fclose(f);
|
2009-06-08 16:21:33 +00:00
|
|
|
advancedFaces.Clear();
|
2009-06-08 06:50:16 +00:00
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void StepFileWriter::WriteWireframe() {
|
2009-06-11 05:57:23 +00:00
|
|
|
fprintf(f, "#%d=GEOMETRIC_CURVE_SET('curves',(", id);
|
|
|
|
int *c;
|
|
|
|
for(c = curves.First(); c; c = curves.NextAfter(c)) {
|
|
|
|
fprintf(f, "#%d", *c);
|
|
|
|
if(curves.NextAfter(c) != NULL) fprintf(f, ",");
|
|
|
|
}
|
|
|
|
fprintf(f, "));\n");
|
|
|
|
fprintf(f, "#%d=GEOMETRICALLY_BOUNDED_WIREFRAME_SHAPE_REPRESENTATION"
|
|
|
|
"('',(#%d,#170),#168);\n", id+1, id);
|
|
|
|
fprintf(f, "#%d=SHAPE_REPRESENTATION_RELATIONSHIP($,$,#169,#%d);\n",
|
|
|
|
id+2, id+1);
|
|
|
|
|
|
|
|
id += 3;
|
|
|
|
curves.Clear();
|
|
|
|
}
|
|
|
|
|