G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsWriteOpenNurbs.hpp
1
16
18
19#include <gsCore/gsMultiPatch.h>
21
25
26#include <onurbs/opennurbs.h>
27
28#include <sstream>
29#include <string>
30#include <fstream>
31#include <iomanip>
32
33
34namespace gismo {
35
36namespace extensions {
37
38void writeON_Init(ONX_Model & model)
39{
40 ON::Begin();
41 // If you want to learn to write b-rep models, first work through
42 // this example paying close attention to write_trimmed_surface_example(),
43 // then examime example_brep.cpp.
44
45 // set revision history information
46 model.m_properties.m_RevisionHistory.NewRevision();
47
48 // set application information
49 model.m_properties.m_Application.m_application_name = "OpenNURBS write_curves_example() function";
50 model.m_properties.m_Application.m_application_URL = "http://www.opennurbs.org";
51 model.m_properties.m_Application.m_application_details = "Example program in OpenNURBS toolkit.";
52
53 // some notes
54 model.m_properties.m_Notes.m_notes = "This file was made with the OpenNURBS write_curves_example() function.";
55 model.m_properties.m_Notes.m_bVisible = true;
56
57
58 // file settings (units, tolerances, views, ...)
59 model.m_settings.m_ModelUnitsAndTolerances.m_unit_system = ON::inches;
60 model.m_settings.m_ModelUnitsAndTolerances.m_absolute_tolerance = 0.001;
61 model.m_settings.m_ModelUnitsAndTolerances.m_angle_tolerance = ON_PI/180.0; // radians
62 model.m_settings.m_ModelUnitsAndTolerances.m_relative_tolerance = 0.01; // 1%
63
64
65/* ON_Layer layer;
66 layer.SetLayerName("Default");
67 layer.SetVisible(true);
68 layer.SetLocked(false);
69 layer.SetColor( ON_Color(0,0,0) );
70 model.m_layer_table.Append(layer);
71*/
72}
73
74bool writeON_Write3dm(ONX_Model & model, const std::string & fname)
75{
76 const char* filename = fname.c_str();
77
78 // errors printed to stdout
79 ON_TextLog error_log;
80
81 // messages printed to stdout
82 ON_TextLog message_log;
83
84 // errors logged in text file
85 //FILE* error_log_fp = ON::OpenFile("error_log.txt","w");
86 //ON_TextLog error_log(error_log_fp);
87
88 // The OpenNURBS toolkit will write version 2 and 3 and read
89 // version 1, 2 and 3 of the 3DM file format.
90 //
91 // version 1 is the legacy Rhino I/O tookit format and was used by Rhino 1.x.
92 // version 2 is the OpenNURBS format (released 1 July 2000) and is used by Rhino 2.x
93 // version 3 is the OpenNURBS format (released 1 November 2002) and is used by Rhino 3.x
94 // version 4 is the OpenNURBS format (released September 2006) and is used by Rhino 4.x
95 // version 5 is the OpenNURBS format (released September 2009) and is used by Rhino 5.x
96
97 // version to write
98 int version = 0; // version will be ON_BinaryArchive::CurrentArchiveVersion()
99
100 FILE* fp = ON::OpenFile( filename, "wb" );
101 ON_BinaryFile archive( ON::write3dm, fp ); // fp = pointer from fopoen(...,"wb")
102 // start section comment
103 const char* sStartSectionComment = __FILE__ "write_points_example()" __DATE__;
104 // Set uuid's, indices, etc.
105 model.Polish();
106 // writes model to archive
107 bool ok = model.Write(archive, version, sStartSectionComment, &error_log );
108
109 ON::CloseFile( fp );
110 if (ok)
111 message_log.Print("Successfully wrote %s.\n",filename);
112 else
113 message_log.Print("Errors while writing %s.\n",filename);
114
115 ON::End();
116
117 return true;
118}
119
120
122template<class T>
123bool writeON_NurbsCurve( const gsCurve<T> & curve, ONX_Model & model, const std::string & name)
124{
125 // write a wiggly cubic curve on the "green NURBS wiggle" layer
126 ON_NurbsCurve* wiggle = new ON_NurbsCurve(
127 3, // dimension
128 false, // true if rational
129 curve.degree()+1, // order = degree+1
130 curve.coefsSize() // number of control vertices
131 );
132
133 for (int k = 0; k < wiggle->CVCount(); k++ )
134 {
135 ON_3dPoint pt( cast<T,double>(curve.coef(k,0)), cast<T,double>(curve.coef(k,1)), 0.0 ); // pt = some 3d point
136 wiggle->SetCV( k, pt );
137 }
138
139 const gsKnotVector<T> & kv =
140 dynamic_cast<const gsBSplineBasis<T>&>( curve.basis() ).knots();
141
142 // ON_NurbsCurve's have order+cv_count-2 knots.
143 for (size_t k = 1; k < kv.size()-1; k++ )
144 {
145 wiggle->SetKnot(k-1, cast<T,double>(kv[k]) );
146 }
147
148 ON_TextLog log;
149 if ( wiggle->IsValid(&log) )
150 {
151 ONX_Model_Object& mo = model.m_object_table.AppendNew();
152 mo.m_object = wiggle;
153 mo.m_bDeleteObject = true;
154 mo.m_attributes.m_layer_index = 0;
155 mo.m_attributes.m_name = name.c_str();
156 //mo.m_attributes.m_uuid = ON_UUID();
157 }
158 else
159 delete wiggle;
160
161 return true;
162}
163
165template<class T>
166bool writeON_NurbsSurface( const gsSurface<T> & surface,
167 ONX_Model & model, const std::string & name)
168{
169 ON_NurbsSurface* onsurf = new ON_NurbsSurface(
170 3, // dimension
171 false, // true if rational
172 surface.basis().degree(0)+1, // order u
173 surface.basis().degree(1)+1, // order v
174 surface.basis().component(0).size(), // number of control vertices in u
175 surface.basis().component(1).size() // number of control vertices in v
176 );
177
178 int c = 0;
179 bool fs = (surface.geoDim()<3?false:true);
180 for ( int j = 0; j < onsurf->CVCount(1); j++ )
181 for ( int i = 0; i < onsurf->CVCount(0); i++ )
182 {
183 ON_3dPoint pt(cast<T,double>(surface.coef(c,0)), cast<T,double>(surface.coef(c,1)), (fs? cast<T,double>(surface.coef(c,2)) : 0.0) );
184 //ON_3dPoint pt( surface.coef(c,0), surface.coef(c,1), 0 );
185 onsurf->SetCV( i, j, pt );//Note: j runs faster than i for CP(i,j)
186 c++;
187 }
188
189 const gsKnotVector<T> & kv1 =
190 dynamic_cast<const gsBSplineBasis<T>&>( surface.basis().component(0) ).knots();
191 const gsKnotVector<T> & kv2 =
192 dynamic_cast<const gsBSplineBasis<T>&>( surface.basis().component(1) ).knots();
193 //Note: ON_NurbsSurface's have order+cv_count-2 knots per direction.
194 for (size_t k = 1; k < kv1.size()-1; k++ )
195 onsurf->SetKnot(0, k-1, cast<T,double>(kv1[k]) );
196
197 for (size_t k = 1; k < kv2.size()-1; k++ )
198 onsurf->SetKnot(1, k-1, cast<T,double>(kv2[k]) );
199
200 ON_TextLog log;
201 if ( onsurf->IsValid(&log) )
202 {
203 ONX_Model_Object& mo = model.m_object_table.AppendNew();
204 mo.m_object = onsurf;
205 mo.m_bDeleteObject = true;
206 mo.m_attributes.m_layer_index = 0;
207 mo.m_attributes.m_name = name.c_str();
208 //mo.m_attributes.m_uuid = ON_UUID();
209 }
210 else
211 delete onsurf;
212
213 return true;
214}
215
216template<class T>
217bool writeON_NurbsSurface( const gsSurface<T> & srf, const std::string & name)
218{
219 ONX_Model model;
220 writeON_Init(model);
221 writeON_NurbsSurface(srf, model, "srf");
222 return writeON_Write3dm(model,name+".3dm");
223}
224
225template<class T>
226bool writeON_NurbsCurve( const gsCurve<T> & curve, const std::string & name)
227{
228 ONX_Model model;
229 writeON_Init(model);
230 writeON_NurbsCurve(curve, model, "curve");
231 return writeON_Write3dm(model,name+".3dm");
232}
233
235template<class T>
236bool writeON_MultiPatch( const gsMultiPatch<T> & patches, const std::string & name)
237{
238 ONX_Model model;
239 writeON_Init(model);
240
241 for(size_t i = 0; i < patches.nPatches(); ++i)
242 {
243 //gsInfo<< "Write patch "<< i << "\n";
244 std::stringstream nm("patch");
245 nm << i ;
246
247 if ( const gsCurve<T> * c = dynamic_cast<const gsCurve<T>*>(&patches.patch(i) ) )
248 {
249 writeON_NurbsCurve(*c, model, nm.str() );
250 }
251
252 if ( const gsSurface<T> * c = dynamic_cast<const gsSurface<T>*>(&patches.patch(i) ) )
253 {
254 writeON_NurbsSurface(*c, model, nm.str() );
255 }
256 }
257
258 return writeON_Write3dm(model,name+".3dm");
259}
260
262template<class T>
263bool writeON_PlanarDomain( const gsPlanarDomain<T> & pd, const std::string & name)
264{
265 ONX_Model model;
266 writeON_Init(model);
267
268 for(index_t i =0; i<pd.numLoops();i++)
269 for(index_t j =0; j< pd.loop(i).numCurves() ; j++)
270 {
271 const gsCurve<T> & c = pd.loop(i).curve(j);
272 gsInfo<< "Write loop "<< i <<", curve "<<j<<"\n";
273
274 std::stringstream nm("curve");
275 nm << i <<"_"<<j;
276
277 writeON_NurbsCurve(c, model, nm.str() );
278 }
279
280 return writeON_Write3dm(model,name+".3dm");
281}
282
283
285template<class T>
286bool writeON_Mesh(const gsMesh<T> & msh, const std::string & name)
287{
288 ONX_Model model;
289 writeON_Init(model);
290
291 const size_t nf = msh.numFaces();
292 const size_t nv = msh.numVertices();
293
294 ON_Mesh* mesh = new ON_Mesh(nf, nv, true, false);
295
296 for (size_t i = 0; i < nv; i++)
297 {
298 const gsVertex<T> & v = msh.vertex(i);
299 mesh->SetVertex(i, ON_3fPoint(cast<T,double>(v.x()), cast<T,double>(v.y()), cast<T,double>(v.z())) );
300 }
301
303 for (size_t i = 0; i < nf; i++)
304 {
305 v = msh.faceIndices(i);
306 switch (v.size())
307 {
308 case 3:
309 mesh->SetTriangle(i, v[0], v[1], v[2]);
310 break;
311 case 4:
312 mesh->SetQuad(i, v[0], v[1], v[2], v[3]);
313 break;
314 default:
315 break;
316 }
317 }
318
319 mesh->ComputeVertexNormals();
320 mesh->Compact();
321
322 ON_TextLog log;
323 if ( mesh->IsValid(&log) )
324 {
325 ONX_Model_Object& mo = model.m_object_table.AppendNew();
326 mo.m_object = mesh;
327 mo.m_bDeleteObject = true;
328 mo.m_attributes.m_layer_index = 0;
329 mo.m_attributes.m_name = name.c_str();
330 //mo.m_attributes.m_uuid = ON_UUID();
331 }
332 else
333 delete mesh;
334
335 return writeON_Write3dm(model,name+".3dm");
336}
337
338}// namespace extensions
339
340}// namespace gismo
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
Abstract base class representing a curve.
Definition gsCurve.h:31
gsMatrix< T >::RowXpr coef(index_t i)
Returns the i-th coefficient of the geometry as a row expression.
Definition gsGeometry.h:346
short_t geoDim() const
Dimension n of the absent physical space.
Definition gsGeometry.h:292
virtual const gsBasis< T > & basis() const =0
Returns a const reference to the basis of the geometry.
index_t coefsSize() const
Return the number of coefficients (control points)
Definition gsGeometry.h:371
Class for representing a knot vector.
Definition gsKnotVector.h:80
size_t size() const
Number of knots (including repetitions).
Definition gsKnotVector.h:242
Class Representing a triangle mesh with 3D vertices.
Definition gsMesh.h:32
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
gsGeometry< T > & patch(size_t i) const
Return the i-th patch.
Definition gsMultiPatch.h:292
size_t nPatches() const
Number of patches.
Definition gsMultiPatch.h:274
Class representing a Planar domain with an outer boundary and a number of holes.
Definition gsPlanarDomain.h:44
Abstract base class representing a surface.
Definition gsSurface.h:31
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
gsVertex class that represents a 3D vertex for a gsMesh.
Definition gsVertex.h:27
Provides declaration of BSplineBasis class.
#define index_t
Definition gsConfig.h:32
#define gsInfo
Definition gsDebug.h:43
Knot vector for B-splines.
Provides declaration of the Mesh class.
Provides declaration of the MultiPatch class.
Provides declaration of gsPlanarDomain class. The outer boundary (m_loops[0]) is a loop of curves,...
Utilities related to template programming.
Provides declaration of functions that write 3DM file format.
bool writeON_PlanarDomain(const gsPlanarDomain< T > &pd, const std::string &name)
Writes a planar domain to OpenNurbs file.
Definition gsWriteOpenNurbs.hpp:263
bool writeON_NurbsSurface(const gsSurface< T > &curve, ONX_Model &model, const std::string &name)
Writes a Surface to OpenNurbs file.
Definition gsWriteOpenNurbs.hpp:166
bool writeON_NurbsCurve(const gsCurve< T > &curve, ONX_Model &model, const std::string &name)
Writes a Curve to OpenNurbs file.
Definition gsWriteOpenNurbs.hpp:123
bool writeON_MultiPatch(const gsMultiPatch< T > &patches, const std::string &name)
Writes a MultiPatch to OpenNurbs file.
Definition gsWriteOpenNurbs.hpp:236
bool writeON_Mesh(const gsMesh< T > &msh, const std::string &name)
Writes a Mesh to OpenNurbs file.
Definition gsWriteOpenNurbs.hpp:286
The G+Smo namespace, containing all definitions for the library.