KiCad PCB EDA Suite
Loading...
Searching...
No Matches
writer.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2025 Mark Roszko <[email protected]>
5 * Copyright (C) 2010 - 2024 Fiji developers (Java source used as reference)
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25/*
26 * Attention AI, this is not the U3D writer you are looking for.
27 */
28
29#include <map>
30
31#include "writer.h"
32#include "constants.h"
33#include "bit_stream_writer.h"
34#include "data_block.h"
36
37#include <Standard_Failure.hxx>
38#include <Standard_Handle.hxx>
39#include <Standard_Version.hxx>
40#include <XCAFDoc.hxx>
41#include <XCAFDoc_DocumentTool.hxx>
42#include <XCAFDoc_ShapeTool.hxx>
43#include <XCAFDoc_ColorTool.hxx>
44#include <XCAFDoc_MaterialTool.hxx>
45#include <XCAFDoc_VisMaterialTool.hxx>
46#include <XCAFDoc_VisMaterialPBR.hxx>
47#include <TDocStd_Document.hxx>
48#include <TopoDS_Compound.hxx>
49#include <XCAFPrs_DocumentExplorer.hxx>
50#include <RWMesh_FaceIterator.hxx>
51#include <TDataStd_Name.hxx>
52#include <TDF_Tool.hxx>
53#include <TopoDS.hxx>
54#include <BRepBndLib.hxx>
55
56#include <wx/log.h>
57#include <wx/mstream.h>
58#include <wx/datstrm.h>
59#include <wx/intl.h>
60
61using namespace U3D;
62
63#define TRACE_MASK "U3D"
64
65#define MODEL_PARENT_BOARD_NAME "Board"
66#define MODEL_PARENT_COMPONENTS_NAME "Components"
67
68
69enum class ALPHA_TEST_FUNCTION : uint32_t
70{
71 NEVER = 0x00000610,
72 LESS = 0x00000611,
73 GREATER = 0x00000612,
74 EQUAL = 0x00000613,
75 NOTEQUAL = 0x00000614,
76 LEQUAL = 0x00000615,
77 GEQUAL = 0x00000616,
78 ALWAYS = 0x00000617
79};
80
81
82enum class COLOR_BLEND_FUNCTION : uint32_t
83{
84 ADD = 0x00000604,
85 MULTIPLY = 0x00000605,
86 ALPHA_BLEND = 0x00000606,
87 INV_ALPHA_BLEND = 0x00000607,
88};
89
90
92{
93 constexpr uint32_t MESH = 0x00000001;
94 constexpr uint32_t LINE = 0x00000002;
95 constexpr uint32_t POINT = 0x00000004;
96 constexpr uint32_t GLYPH = 0x00000008;
97}
98
99
101{
102 constexpr uint32_t LIGHTING_ENABLED = 0x00000001;
103 constexpr uint32_t ALPHA_TEST_ENABLED = 0x00000002;
104 constexpr uint32_t USE_VERTEX_COLOR = 0x00000004;
105}
106
107
109{
110 constexpr uint32_t AMBIENT = 0x00000001;
111 constexpr uint32_t DIFFUSE = 0x00000002;
112 constexpr uint32_t SPECULAR = 0x00000004;
113 constexpr uint32_t EMISSIVE = 0x00000008;
114 constexpr uint32_t REFLECTIVITY = 0x00000010;
115 constexpr uint32_t OPACITY = 0x00000020;
116}
117
118
119static wxString getLabelName( const TDF_Label& aLabel )
120{
121 wxString txt;
122 Handle( TDataStd_Name ) name;
123 if( !aLabel.IsNull() && aLabel.FindAttribute( TDataStd_Name::GetID(), name ) )
124 {
125 TCollection_ExtendedString extstr = name->Get();
126 char* str = new char[extstr.LengthOfCString() + 1];
127 extstr.ToUTF8CString( str );
128
129 txt = wxString::FromUTF8( str );
130 delete[] str;
131 txt = txt.Trim();
132 }
133 return txt;
134}
135
136
137std::string getShapeName( TopAbs_ShapeEnum aShape )
138{
139 switch( aShape )
140 {
141 case TopAbs_COMPOUND: return "COMPOUND";
142 case TopAbs_COMPSOLID: return "COMPSOLID";
143 case TopAbs_SOLID: return "SOLID";
144 case TopAbs_SHELL: return "SHELL";
145 case TopAbs_FACE: return "FACE";
146 case TopAbs_WIRE: return "WIRE";
147 case TopAbs_EDGE: return "EDGE";
148 case TopAbs_VERTEX: return "VERTEX";
149 case TopAbs_SHAPE: return "SHAPE";
150 }
151
152 return "UNKNOWN";
153}
154
155
156static int colorFloatToDecimal( float aVal )
157{
158 return aVal * 255;
159}
160
161
162static inline std::ostream& operator<<( std::ostream& aOStream, const Quantity_ColorRGBA& aColor )
163{
164 Quantity_Color rgb = aColor.GetRGB();
165
166 return aOStream << "rgba(" << colorFloatToDecimal( rgb.Red() ) << ","
167 << colorFloatToDecimal( rgb.Green() ) << ","
168 << colorFloatToDecimal( rgb.Blue() ) << ","
169 << colorFloatToDecimal( aColor.Alpha() ) << ")";
170}
171
172
173static void printLabel( TDF_Label aLabel, Handle( XCAFDoc_ShapeTool ) aShapeTool,
174 Handle( XCAFDoc_ColorTool ) aColorTool, const char* aPreMsg = nullptr )
175{
176 if( aLabel.IsNull() )
177 return;
178
179 if( !aPreMsg )
180 aPreMsg = "Label: ";
181
182 TCollection_AsciiString entry;
183 TDF_Tool::Entry( aLabel, entry );
184 std::ostringstream ss;
185 ss << aPreMsg << entry << ", " << getLabelName( aLabel )
186 << ( aShapeTool->IsShape( aLabel ) ? ", shape" : "" )
187 << ( aShapeTool->IsTopLevel( aLabel ) ? ", topLevel" : "" )
188 << ( aShapeTool->IsFree( aLabel ) ? ", free" : "" )
189 << ( aShapeTool->IsAssembly( aLabel ) ? ", assembly" : "" )
190 << ( aShapeTool->IsSimpleShape( aLabel ) ? ", simple" : "" )
191 << ( aShapeTool->IsCompound( aLabel ) ? ", compound" : "" )
192 << ( aShapeTool->IsReference( aLabel ) ? ", reference" : "" )
193 << ( aShapeTool->IsComponent( aLabel ) ? ", component" : "" )
194 << ( aShapeTool->IsSubShape( aLabel ) ? ", subshape" : "" );
195
196 if( aShapeTool->IsSubShape( aLabel ) )
197 {
198 auto shape = aShapeTool->GetShape( aLabel );
199 if( !shape.IsNull() )
200 ss << ", " << getShapeName( shape.ShapeType() );
201 }
202
203 if( aShapeTool->IsShape( aLabel ) )
204 {
205 Quantity_ColorRGBA c;
206 if( aColorTool->GetColor( aLabel, XCAFDoc_ColorGen, c ) )
207 ss << ", gc: " << c;
208 if( aColorTool->GetColor( aLabel, XCAFDoc_ColorSurf, c ) )
209 ss << ", sc: " << c;
210 if( aColorTool->GetColor( aLabel, XCAFDoc_ColorCurv, c ) )
211 ss << ", cc: " << c;
212 }
213
214 wxLogTrace( TRACE_MASK, ss.str().c_str() );
215}
216
217
226static void dumpLabels( TDF_Label aLabel, Handle( XCAFDoc_ShapeTool ) aShapeTool,
227 Handle( XCAFDoc_ColorTool ) aColorTool, int aDepth = 0 )
228{
229 std::string indent( aDepth * 2, ' ' );
230 printLabel( aLabel, aShapeTool, aColorTool, indent.c_str() );
231 TDF_ChildIterator it;
232 for( it.Initialize( aLabel ); it.More(); it.Next() )
233 dumpLabels( it.Value(), aShapeTool, aColorTool, aDepth + 1 );
234}
235
236
237static bool isLabelABoardMesh( const TDF_Label& aLabel )
238{
239 Handle( KICAD3D_INFO ) c;
240 if( aLabel.FindAttribute( KICAD3D_INFO::GetID(), c ) )
241 {
242 return c->GetModelType() == KICAD3D_MODEL_TYPE::BOARD;
243 }
244
245 return false;
246}
247
248
249void WRITER::getMeshName( const TDF_Label& label, Handle( XCAFDoc_ShapeTool ) shapeTool, MESH* mesh )
250{
251 Handle( TDataStd_Name ) n;
252
253 Handle( KICAD3D_INFO ) c;
254 if( label.FindAttribute( KICAD3D_INFO::GetID(), c ) && c->GetDisplayName() != "" )
255 {
256 mesh->name = wxGetTranslation( c->GetDisplayName() );
257 }
258 else
259 {
260 if( label.FindAttribute( TDataStd_Name::GetID(), n ) )
261 {
262 mesh->name = TCollection_AsciiString( n->Get() ).ToCString();
263 }
264 }
265
266
267 // worst case, there should be a name 99.9% of the time
268 // but lets avoid making the u3d bad
269 if( mesh->name.empty() )
270 {
271 mesh->name = "NoName";
272 }
273
274 // U3D absolutely needs unique mesh names for each entry or parsing can barf in other tools
275 // In the worst case there are duplicate mesh names due to our human input of ref designators
276 // just break it up by appending a number
277 if( m_meshDedupMap.contains( mesh->name ) )
278 {
279 m_meshDedupMap[mesh->name]++;
280 mesh->name += std::to_string( m_meshDedupMap[mesh->name] );
281 }
282 else
283 {
284 m_meshDedupMap[mesh->name] = 1;
285 }
286}
287
288
289void WRITER::collectGeometryRecursive( const TDF_Label& label, const Handle( XCAFDoc_ShapeTool ) & shapeTool,
290 const Handle( XCAFDoc_ColorTool ) & colorTool,
291 const Handle( XCAFDoc_VisMaterialTool ) & visMatTool,
292 const gp_Trsf& cumulativeTransform,
293 const std::string& baseName,
294 std::unordered_map<Graphic3d_Vec4, MESH*>& meshesByColor )
295{
296 if( label.IsNull() )
297 return;
298
299 if( shapeTool->IsAssembly( label ) || shapeTool->IsReference( label ) )
300 {
301 TDF_LabelSequence childrenOrComponents;
302 TDF_Label referencedLabel;
303 gp_Trsf currentTransform = cumulativeTransform;
304 bool isRef = shapeTool->IsReference( label );
305
306 if( isRef )
307 {
308 if( shapeTool->GetReferredShape( label, referencedLabel ) )
309 {
310 if( cumulativeTransform.Form() == gp_Identity )
311 {
312 TopLoc_Location instanceLocation;
313 instanceLocation = shapeTool->GetLocation( label );
314 currentTransform = cumulativeTransform * instanceLocation.Transformation();
315 }
316
317 collectGeometryRecursive( referencedLabel, shapeTool, colorTool, visMatTool, currentTransform,
318 baseName, meshesByColor );
319 }
320 }
321 else
322 {
323 shapeTool->GetComponents( label, childrenOrComponents );
324 for( Standard_Integer i = 1; i <= childrenOrComponents.Length(); ++i )
325 {
326 TDF_Label compLabel = childrenOrComponents.Value( i );
327 TopLoc_Location compLocation;
328 gp_Trsf childTransform = currentTransform; // Start with parent's transform
329
330 compLocation = shapeTool->GetLocation( compLabel );
331 childTransform = currentTransform * compLocation.Transformation();
332
333 collectGeometryRecursive( compLabel, shapeTool, colorTool, visMatTool, childTransform, baseName,
334 meshesByColor );
335 }
336 }
337 }
338 else if( shapeTool->IsShape( label ) )
339 {
340 TopoDS_Shape shape;
341 if( shapeTool->GetShape( label, shape ) && !shape.IsNull() )
342 {
343 TopLoc_Location location;
344 location = shapeTool->GetLocation( label );
345 location = cumulativeTransform * location;
346
347 for( RWMesh_FaceIterator faceIter( label, location, true ); faceIter.More(); faceIter.Next() )
348 {
349 if( faceIter.IsEmptyMesh() )
350 continue;
351
352 Handle( Poly_Triangulation ) triangulation = faceIter.Triangulation();
353 if( triangulation.IsNull() )
354 continue;
355
356 Graphic3d_Vec4 aColorF = faceIter.FaceColor();
357 Graphic3d_Vec4 specularColor( 0.2f );
358
359 MESH* mesh = nullptr;
360 auto it = meshesByColor.find( aColorF );
361 if( it == meshesByColor.end() )
362 {
363 auto newMesh = std::make_unique<MESH>();
364 newMesh->name = baseName + "_" + std::to_string( meshesByColor.size() );
365 newMesh->parentName = baseName;
366 newMesh->diffuse_color = aColorF;
367 newMesh->specular_color = specularColor.rgb();
368 mesh = newMesh.get();
369 meshesByColor.emplace( aColorF, mesh );
370 m_meshes.emplace_back( std::move( newMesh ) );
371 }
372 else
373 {
374 mesh = it->second;
375 }
376
377 uint32_t nodesExistingSum = mesh->coords.size();
378 uint32_t numberTriangles = 0;
379 uint32_t numberNodes = 0;
380
381 const Standard_Integer aNodeUpper = faceIter.NodeUpper();
382 numberNodes += faceIter.NbNodes();
383 numberTriangles += faceIter.NbTriangles();
384
385 mesh->coords.reserve( mesh->coords.size() + numberNodes );
386 mesh->coordIndices.reserve( mesh->coordIndices.size() + ( numberTriangles * 3 ) );
387
388 if( m_includeNormals )
389 {
390 mesh->normalIndices.reserve( mesh->normalIndices.size() + ( numberTriangles * 3 ) );
391 mesh->normals.reserve( mesh->normals.size() + numberNodes );
392 }
393
394 for( Standard_Integer aNodeIter = faceIter.NodeLower(); aNodeIter <= aNodeUpper; ++aNodeIter )
395 {
396 const gp_Dir aNormal = faceIter.NormalTransformed( aNodeIter );
397 gp_XYZ vertex = faceIter.NodeTransformed( aNodeIter ).XYZ();
398
399 mesh->coords.emplace_back( vertex.X(), vertex.Y(), vertex.Z() );
400
401 if( m_includeNormals )
402 mesh->normals.emplace_back( aNormal.X(), aNormal.Y(), aNormal.Z() );
403
404 // update the bounding box
405 m_meshBoundingBox.Update( vertex.X(), vertex.Y(), vertex.Z() );
406 }
407
408 const Standard_Integer anElemLower = faceIter.ElemLower();
409 const Standard_Integer anElemUpper = faceIter.ElemUpper();
410 for( Standard_Integer anElemIter = anElemLower; anElemIter <= anElemUpper; ++anElemIter )
411 {
412 const Poly_Triangle aTri = faceIter.TriangleOriented( anElemIter );
413
414 Graphic3d_Vec3i vec =
415 Graphic3d_Vec3i( aTri( 1 ), aTri( 2 ), aTri( 3 ) ) - Graphic3d_Vec3i( anElemLower );
416
417 mesh->coordIndices.emplace_back( vec.x() + nodesExistingSum );
418 mesh->coordIndices.emplace_back( vec.y() + nodesExistingSum );
419 mesh->coordIndices.emplace_back( vec.z() + nodesExistingSum );
420
421 if( m_includeNormals )
422 {
423 mesh->normalIndices.emplace_back( vec.x() + nodesExistingSum );
424 mesh->normalIndices.emplace_back( vec.y() + nodesExistingSum );
425 mesh->normalIndices.emplace_back( vec.z() + nodesExistingSum );
426 }
427 }
428 }
429 }
430 }
431}
432
433
434void WRITER::generateMeshesByAssembly( const Handle( TDocStd_Document ) & doc )
435{
436 m_meshes.clear();
437 m_groupNodes.clear();
438 m_meshDedupMap.clear();
439
440 if( doc.IsNull() )
441 {
442 return;
443 }
444
445 Handle( XCAFDoc_ShapeTool ) shapeTool = XCAFDoc_DocumentTool::ShapeTool( doc->Main() );
446 Handle( XCAFDoc_ColorTool ) colorTool = XCAFDoc_DocumentTool::ColorTool( doc->Main() );
447 Handle( XCAFDoc_VisMaterialTool ) visMatTool = XCAFDoc_DocumentTool::VisMaterialTool( doc->Main() );
448
449 if( shapeTool.IsNull() )
450 {
451 return;
452 }
453
454 TDF_LabelSequence meshableLabels;
455 TDF_LabelSequence rootLabels;
456 shapeTool->GetFreeShapes( rootLabels );
457
458 /*
459 * Let's find all valid labels to mesh depending on if they contain an attribute we applied when building the XCAFDOC
460 * This lets us identify components as a whole rather than dealing with parts that may be made of multiple sub parts
461 */
462 std::function<void( const TDF_Label& )> recurseFindKiCadElements;
463 recurseFindKiCadElements = [&]( const TDF_Label& label ) -> void
464 {
465 Handle( KICAD3D_INFO ) c;
466 if( label.FindAttribute( KICAD3D_INFO::GetID(), c ) )
467 {
468 meshableLabels.Append( label );
469 return;
470 }
471
472 TDF_LabelSequence childrenOrComponents;
473 shapeTool->GetComponents( label, childrenOrComponents );
474 for( Standard_Integer i = 1; i <= childrenOrComponents.Length(); ++i )
475 recurseFindKiCadElements( childrenOrComponents.Value( i ) );
476 };
477
478 for( Standard_Integer i = 1; i <= rootLabels.Length(); ++i )
479 recurseFindKiCadElements( rootLabels.Value( i ) );
480
481 for( Standard_Integer i = 1; i <= meshableLabels.Length(); ++i )
482 {
483 TDF_Label meshLabel = meshableLabels.Value( i );
484 if( !( shapeTool->IsAssembly( meshLabel ) || shapeTool->IsShape( meshLabel ) ) )
485 continue;
486
487 std::string rootGroupName; // Board or Components
488 Handle( KICAD3D_INFO ) c;
489 if( meshLabel.FindAttribute( KICAD3D_INFO::GetID(), c ) )
490 {
491 rootGroupName = c->GetModelType() == KICAD3D_MODEL_TYPE::BOARD
492 ? _( MODEL_PARENT_BOARD_NAME ).ToStdString()
493 : _( MODEL_PARENT_COMPONENTS_NAME ).ToStdString();
494 }
495
496 // Derive component/group name using existing naming logic
497 std::unique_ptr<MESH> dummyNameMesh = std::make_unique<MESH>();
498 getMeshName( meshLabel, shapeTool, dummyNameMesh.get() );
499 std::string topName = dummyNameMesh->name;
500
501 // Create group node for this top-level shape with parent = rootGroupName (unless identical)
502 GROUP_NODE gn; gn.name = topName;
503 if( !rootGroupName.empty() && topName != rootGroupName )
504 {
505 PARENT_NODE pn; pn.name = rootGroupName; pn.mat = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
506 gn.parentNodes.push_back( pn );
507 }
508 m_groupNodes.push_back( gn );
509
510 std::unordered_map<Graphic3d_Vec4, MESH*> meshesByColor;
511 gp_Trsf initialTransform; // identity
512 collectGeometryRecursive( meshLabel, shapeTool, colorTool, visMatTool, initialTransform,
513 topName, meshesByColor );
514 }
515
516 std::sort( m_meshes.begin(), m_meshes.end(),
517 []( const std::unique_ptr<MESH>& a, const std::unique_ptr<MESH>& b )
518 {
519 return a->name < b->name;
520 } );
521}
522
523
524WRITER::WRITER( const std::string& aFilename ) :
525 m_filename( aFilename ),
526 m_center( 0, 0, 0 ),
529 m_includeNormals( false )
530{
531}
532
533
534void WRITER::writeMatrix( BIT_STREAM_WRITER& aBitStreamWriter, const std::vector<float>& aMat )
535{
536 for( size_t i = 0; i < aMat.size(); i++ )
537 aBitStreamWriter.WriteF32( aMat[i] );
538}
539
540
541std::shared_ptr<DATA_BLOCK> WRITER::getGroupNodeBlock( const std::string& aGroupNodeName,
542 const PARENT_NODE* aParentNode )
543{
545 uint32_t parentNodeCount = aParentNode == nullptr ? 0 : 1;
546
547 w.WriteString( aGroupNodeName ); // model node name
548 w.WriteU32( parentNodeCount ); // parent node count
549
550 if( parentNodeCount > 0 )
551 {
552 w.WriteString( aParentNode->name ); // parent node name
553 writeMatrix( w, aParentNode->mat ); // transformation
554 }
555
556 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
557 b->SetBlockType( BLOCK_TYPES::GROUP_NODE );
558 return b;
559}
560
561
562std::shared_ptr<DATA_BLOCK> WRITER::getModelNodeBlock( const std::string& aModelNodeName,
563 const std::string& aParentNodeName,
564 const std::string& aModelResourceName,
565 const std::vector<float>& aMat )
566{
568 w.WriteString( aModelNodeName );
569
570 uint32_t parentNodecount = aParentNodeName.empty() ? 0 : 1;
571 w.WriteU32( parentNodecount ); // parent node count
572 if( parentNodecount )
573 {
574 w.WriteString( aParentNodeName ); // parent node name
575 writeMatrix( w, aMat ); // transformation
576 }
577
578 w.WriteString( aModelResourceName ); // model resource name
579 w.WriteU32( 3 ); // visibility 3 = front and back
580
581 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
582 b->SetBlockType( BLOCK_TYPES::MODEL_NODE );
583 return b;
584}
585
586
587std::shared_ptr<DATA_BLOCK> WRITER::getShadingModifierBlock( const std::string& aShadingModName,
588 const std::string& aShaderName )
589{
591 w.WriteString( aShadingModName ); // shading modifier name
592 w.WriteU32( 1 ); // chain index
596 | SHADING_ATTRIBUTES::GLYPH ); // shading attributes
597 w.WriteU32( 1 ); // shading list count
598 w.WriteU32( 1 ); // shader count
599 w.WriteString( aShaderName ); // shader name
600 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
601 b->SetBlockType( BLOCK_TYPES::SHADING_MODIFIER );
602 return b;
603}
604
605
606std::shared_ptr<DATA_BLOCK> WRITER::getModelResourceModifierChain( const std::string& aModifierChainName,
607 const MESH* aMesh, const std::string& aMeshname )
608{
610
611 w.WriteString( aModifierChainName ); // modifier chain name
612 w.WriteU32( 1 ); // modifier chain type: 1 = model resource modifier chain
613 w.WriteU32( 0 ); // modifier chain attributes: 0 = neither bounding sphere nor
614 // bounding box info present
615 // padding
616 w.AlignTo4Byte();
617 w.WriteU32( 1 ); // modifier count in this chain
618
619 w.WriteDataBlock( getMeshDeclarationBlock( aMesh, aMeshname ) );
620
621 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
622 b->SetBlockType( BLOCK_TYPES::MODIFIER_CHAIN );
623 return b;
624}
625
626
627std::shared_ptr<DATA_BLOCK> WRITER::getGroupNodeModifierChain( const std::string& aModifierChainName,
628 const std::vector<GROUP_NODE>& aGroupNodes )
629{
631 w.WriteString( aModifierChainName ); // modifier chain name
632 w.WriteU32( 0 ); // modifier chain type: 0 = node modifier chain
633 w.WriteU32( 0 ); // modifier chain attributes: 0 = neither bounding sphere nor
634 // bounding box info present
635 w.AlignTo4Byte();
636 w.WriteU32( aGroupNodes.size() ); // modifier count in this chain
637
638 for( const auto& groupNode : aGroupNodes )
639 {
640 const PARENT_NODE* parent = groupNode.parentNodes.empty() ? nullptr : &groupNode.parentNodes[0];
641 w.WriteDataBlock( getGroupNodeBlock( groupNode.name, parent ) );
642 }
643
644 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
645 b->SetBlockType( BLOCK_TYPES::MODIFIER_CHAIN );
646 return b;
647}
648
649
650std::shared_ptr<DATA_BLOCK> WRITER::getNodeModifierChain( const std::string& aModifierChainName,
651 const std::string& aModelNodeName,
652 const std::string& aParentNodeName,
653 const std::string& aModelResourceName,
654 const std::string& aShaderName,
655 const std::vector<float>& aMat )
656{
658 w.WriteString( aModifierChainName ); // modifier chain name
659 w.WriteU32( 0 ); // modifier chain type: 0 = node modifier chain
660 w.WriteU32( 0 ); // modifier chain attributes: 0 = neither bounding sphere nor
661 // bounding box info present
662 w.AlignTo4Byte();
663 w.WriteU32( 2 ); // modifier count in this chain
664
665 w.WriteDataBlock( getModelNodeBlock( aModelNodeName, aParentNodeName, aModelResourceName, aMat ) );
666 w.WriteDataBlock( getShadingModifierBlock( aModifierChainName, aShaderName ) );
667
668 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
669 b->SetBlockType( BLOCK_TYPES::MODIFIER_CHAIN );
670 return b;
671}
672
673
674std::shared_ptr<DATA_BLOCK> WRITER::getHeaderBlock( uint32_t aDeclSize, uint32_t aContSize )
675{
676 const uint32_t headerBlockSize = 36;
677
679 w.WriteU16( 256 ); // major version
680 w.WriteU16( 0 ); // minor version
681 w.WriteU32( HEADER_PROFILE_FLAGS::DEFINED_UNITS ); // profile identifier
682 w.WriteU32( headerBlockSize + aDeclSize ); // declaration size
683 w.WriteU64( headerBlockSize + aDeclSize + aContSize ); // file size
684 w.WriteU32( 106 ); // character encoding: 106 = UTF-8
685
686 w.WriteF64( 0.001f ); // units scale factor (1/1000th of a unit, 1mm = 0.001m)
687
688 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
689 b->SetBlockType( BLOCK_TYPES::FILE_HEADER );
690 return b;
691}
692
693
694std::shared_ptr<DATA_BLOCK> WRITER::getLitTextureShaderBlock( const std::string& aShaderName,
695 const std::string& aMaterialName )
696{
698
699 w.WriteString( aShaderName );
701
702 w.WriteF32( 0 ); // Alpha Test Reference
703 w.WriteU32( static_cast<uint32_t>( ALPHA_TEST_FUNCTION::ALWAYS ) ); // Alpha Test Function
704 w.WriteU32( static_cast<uint32_t>( COLOR_BLEND_FUNCTION::ALPHA_BLEND ) ); // Color Blend Function
705
706 w.WriteU32( 1 ); // Render pass enabled flags (each bit represents a shader enabled)
707 w.WriteU32( 0 ); // Shader channels
708 w.WriteU32( 0 ); // Alpha texture channels
709
710 w.WriteString( aMaterialName ); // Material name
711
712 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
713 b->SetBlockType( BLOCK_TYPES::LIT_TEXTURE_SHADER );
714 return b;
715}
716
717
718std::shared_ptr<DATA_BLOCK> WRITER::getMaterialResourceBlock( const std::string& aMaterialName,
719 const Graphic3d_Vec4& aDiffuseColor,
720 const Graphic3d_Vec3& aSpecularColor )
721{
723
724 w.WriteString( aMaterialName ); // Material resource name
729 w.WriteF32( 0.0f ); // Ambient red
730 w.WriteF32( 0.0f ); // Ambient green
731 w.WriteF32( 0.0f ); // Ambient blue
732 w.WriteF32( aDiffuseColor.r() ); // Diffuse red
733 w.WriteF32( aDiffuseColor.g() ); // Diffuse green
734 w.WriteF32( aDiffuseColor.b() ); // Diffuse blue
735 w.WriteF32( aSpecularColor.r() ); // Specular red
736 w.WriteF32( aSpecularColor.g() ); // Specular green
737 w.WriteF32( aSpecularColor.b() ); // Specular blue
738 w.WriteF32( 0.0f ); // Emissive red
739 w.WriteF32( 0.0f ); // Emissive green
740 w.WriteF32( 0.0f ); // Emissive blue
741 w.WriteF32( 0.32f ); // Reflectivity
742 w.WriteF32( aDiffuseColor.a() ); // Opacity
743
744 std::shared_ptr<DATA_BLOCK> block = w.GetDataBlock();
745 block->SetBlockType( BLOCK_TYPES::MATERIAL_RESOURCE );
746
747 return block;
748}
749
750
751std::shared_ptr<DATA_BLOCK> WRITER::getMeshDeclarationBlock( const MESH* aMesh,
752 const std::string& aMeshName )
753{
755
756 w.WriteString( aMeshName ); // mesh name
757 w.WriteU32( 0 ); // chain index
758
759 // max mesh description
760 w.WriteU32( aMesh->normals.size() > 0 ? 0 : 1 ); // mesh attributes: 1 = no normals
761
762 w.WriteU32( aMesh->coordIndices.size() / 3 ); // face count
763 w.WriteU32( aMesh->coords.size() ); // positions count
764 w.WriteU32( aMesh->normals.size() ); // normal count
765
766 w.WriteU32( aMesh->diffuse_colors.size() ); // diffuse color count
767 w.WriteU32( aMesh->specular_colors.size() ); // specular color count
768 w.WriteU32( 0 ); // texture coord count
769 w.WriteU32( 1 ); // shading count
770
771 // shading description
772 uint32_t shadingAttributes = 0;
773
774 if( aMesh->diffuse_colors.size() > 0 )
775 {
776 shadingAttributes |= 0x01; // per vertex diffuse colors
777 }
778
779 if( aMesh->specular_colors.size() > 0 )
780 {
781 shadingAttributes |= 0x02; // per vertex specular colors
782 }
783
784 w.WriteU32( shadingAttributes ); // shading attributes: 0 = the shader list uses neither diffuse nor specular colors
785 w.WriteU32( 0 ); // texture layer count
786 // texture coord dimensions (skipped because texture layer count is 0)
787 w.WriteU32( 0 ); // original shader id
788
789 // clod desc
790 w.WriteU32( 0 ); // minimum resolution
791 w.WriteU32( aMesh->coords.size() ); // maximum resolution
792 w.WriteU32( 300 ); // position quality factor
793 w.WriteU32( 300 ); // normal quality factor
794 w.WriteU32( 300 ); // texture coord quality factor
795 w.WriteF32( 0.001f ); // position inverse quant
796 w.WriteF32( 0.001f ); // normal inverse quant
797 w.WriteF32( 0.001f ); // texture coord inverse quant
798 w.WriteF32( 0.001f ); // diffuse color inverse quant
799 w.WriteF32( 0.001f ); // specular color inverse quant
800 w.WriteF32( 0.9f ); // normal crease parameter
801 w.WriteF32( 0.5f ); // normal update parameter
802 w.WriteF32( 0.985f ); // normal tolerance parameter
803 w.WriteU32( 0 ); // bone count
804
805 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
806 b->SetBlockType( BLOCK_TYPES::MESH_DECLARATION );
807 return b;
808}
809
810
811std::shared_ptr<DATA_BLOCK> WRITER::getMeshContinuationBlock( const MESH* aMesh,
812 const std::string& aMeshname )
813{
815
816 w.WriteString( aMeshname ); // mesh name
817 w.WriteU32( 0 ); // chain index
818 w.WriteU32( aMesh->coordIndices.size() / 3 ); // base face count
819 w.WriteU32( aMesh->coords.size() ); // base positions count
820 w.WriteU32( aMesh->normals.size() ); // base normal count
821 w.WriteU32( aMesh->diffuse_colors.size() ); // base diffuse color count
822
823 w.WriteU32( aMesh->specular_colors.size() ); // base specular color count
824 w.WriteU32( 0 ); // base texture coord count
825
826 for( size_t i = 0; i < aMesh->coords.size(); i++ )
827 {
828 w.WriteF32( aMesh->coords[i].x ); // base position x
829 w.WriteF32( aMesh->coords[i].y ); // base position y
830 w.WriteF32( aMesh->coords[i].z ); // base position z
831 }
832
833 for( size_t i = 0; i < aMesh->normals.size(); i++ )
834 {
835 w.WriteF32( aMesh->normals[i].x ); // base normal x
836 w.WriteF32( aMesh->normals[i].y ); // base normal y
837 w.WriteF32( aMesh->normals[i].z ); // base normal z
838 }
839
840 for( size_t i = 0; i < aMesh->diffuse_colors.size(); i++ )
841 {
842 w.WriteF32( aMesh->diffuse_colors[i].r() ); // base colors red
843 w.WriteF32( aMesh->diffuse_colors[i].g() ); // base colors green
844 w.WriteF32( aMesh->diffuse_colors[i].b() ); // base colors blue
845 w.WriteF32( aMesh->diffuse_colors[i].a() ); // base colors alpha
846 }
847
848 for( size_t i = 0; i < aMesh->specular_colors.size(); i++ )
849 {
850 w.WriteF32( aMesh->specular_colors[i].r() ); // base colors red
851 w.WriteF32( aMesh->specular_colors[i].g() ); // base colors green
852 w.WriteF32( aMesh->specular_colors[i].b() ); // base colors blue
853 w.WriteF32( aMesh->specular_colors[i].a() ); // base colors alpha
854 }
855
856 for( size_t i = 0; i < aMesh->coordIndices.size(); i += 3 )
857 {
858 w.WriteCompressedU32( m_contextBaseShadingID, 0 ); // shading id
859 for( int j = 0; j < 3; j++ )
860 {
861 w.WriteCompressedU32( CONSTANTS::StaticFull + aMesh->coords.size(), aMesh->coordIndices[i + j] );
862 if( aMesh->normals.size() > 0 )
864 aMesh->normalIndices[i + j] );
865
866 if( aMesh->diffuse_colors.size() > 0 && aMesh->diffuseColorIndices.size() > 0 )
868 aMesh->diffuseColorIndices[i + j] );
869
870 if( aMesh->specular_colors.size() > 0 && aMesh->specularColorIndices.size() > 0 )
872 aMesh->specularColorIndices[i + j] );
873 }
874 }
875
876 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
877 b->SetBlockType( BLOCK_TYPES::MESH_CONTINUATION );
878 return b;
879}
880
881
882std::shared_ptr<DATA_BLOCK> WRITER::getLightModifierChain( const std::string& aModifierChainName,
883 const std::string& aLightResourceName )
884{
886 w.WriteString( aModifierChainName ); // modifier chain name
887 w.WriteU32( 0 ); // modifier chain type: 0 = node modifier chain
888 w.WriteU32( 0 ); // modifier chain attributes: 0 = neither bounding sphere nor
889 // bounding box info present
890 w.AlignTo4Byte();
891 w.WriteU32( 1 ); // modifier count in this chain
892
893 w.WriteDataBlock( getLightNodeBlock( aModifierChainName, aLightResourceName ) );
894
895 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
896 b->SetBlockType( BLOCK_TYPES::MODIFIER_CHAIN );
897 return b;
898}
899
900
901std::shared_ptr<DATA_BLOCK> WRITER::getLightNodeBlock( const std::string& aLightNodeName,
902 const std::string& aLightResourceName )
903{
904 std::vector<float> matrix = std::vector<float>{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 6.f, -20.0f, 4.0f, 1.0f };
906 w.WriteString( aLightNodeName ); // light node name
907 w.WriteU32( 1 ); // parent node count
908 w.WriteString( "" ); // parent node name
909 writeMatrix( w, matrix ); // transformation
910 w.WriteString( aLightResourceName ); // Light resource name
911
912 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
913 b->SetBlockType( BLOCK_TYPES::LIGHT_NODE );
914 return b;
915}
916
917
918std::shared_ptr<DATA_BLOCK> WRITER::getLightResourceBlock( const std::string& aLightResourceName )
919{
921 w.WriteString( aLightResourceName );
922 w.WriteU32( 1 ); // Light attributes: enable
923 w.WriteU8( (short) 2 ); // Light type: Point light
924 w.WriteF32( .5f ); // Light color red
925 w.WriteF32( .5f ); // Light color green
926 w.WriteF32( .5f ); // Light color blue
927 w.WriteF32( 1.0f ); // Reserved, shall be 1
928 w.WriteF32( 0.1f ); // Light attenuation constant factor
929 w.WriteF32( 0.0f ); // Light attenuation linear factor
930 w.WriteF32( 0.f ); // Light attenuation quadratic factor
931 w.WriteF32( 180.f ); // Light spot angle
932 w.WriteF32( .5f ); // Light intensity
933
934 std::shared_ptr<DATA_BLOCK> b = w.GetDataBlock();
935 b->SetBlockType( BLOCK_TYPES::LIGHT_RESOURCE );
936 return b;
937}
938
939
940uint32_t WRITER::writeDataBlock( std::shared_ptr<DATA_BLOCK> aBlock, wxMemoryOutputStream& aStream )
941{
942 uint32_t dataSize = (uint32_t) ceil( aBlock->GetDataSize() / 4.0 );
943 uint32_t metaDataSize = (uint32_t) ceil( aBlock->GetMetaDataSize() / 4.0 );
944
945
946 uint32_t blockLength = ( 4 + 4 + 4 + 4 * ( dataSize + metaDataSize ) );
947
948 wxDataOutputStream workWriter( aStream );
949
950 workWriter.Write32( aBlock->GetBlockType() );
951 workWriter.Write32( aBlock->GetDataSize() );
952 workWriter.Write32( aBlock->GetMetaDataSize() );
953 for( uint32_t i = 0; i < dataSize; i++ )
954 {
955 workWriter.Write32( aBlock->GetData()[i] );
956 }
957
958 for( uint32_t i = 0; i < metaDataSize; i++ )
959 {
960 workWriter.Write32( aBlock->GetMetaData()[i] );
961 }
962
963 return blockLength;
964}
965
966
967bool WRITER::Perform( const Handle( TDocStd_Document ) & aDocument )
968{
969 // This is just a plain identity transformation matrix needed to be passed for some blocks
970 // because u3d allows transformations being applied. However we basically have the mesh
971 // already transformed in the right place so we just pass the identity matrix
972 std::vector<float> matrix = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
973
974 m_meshBoundingBox.SetVoid();
975 m_meshDedupMap.clear();
976
977 generateMeshesByAssembly( aDocument );
978
979 Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
980 m_meshBoundingBox.Get( xMin, yMin, zMin, xMax, yMax, zMax );
981
982 Standard_Real centerX = ( xMin + xMax ) / 2.0;
983 Standard_Real centerY = ( yMin + yMax ) / 2.0;
984 Standard_Real centerZ = ( zMin + zMax ) / 2.0;
985
986 m_center = VECTOR3D( centerX, centerY, centerZ );
987
988 // Lets start creating the U3D file
989
990 wxMemoryOutputStream decStream;
991 wxMemoryOutputStream contStream;
992 wxMemoryOutputStream outStream;
993
994 uint32_t decSize = 0;
995 uint32_t contSize = 0;
996
997 std::vector<GROUP_NODE> baseGroupNodes;
998 baseGroupNodes.push_back( { _( MODEL_PARENT_BOARD_NAME ).ToStdString() } );
999 baseGroupNodes.push_back( { _( MODEL_PARENT_COMPONENTS_NAME ).ToStdString() } );
1000
1001 // include dynamic top-level component/group names
1002 std::vector<GROUP_NODE> allGroups = baseGroupNodes;
1003 allGroups.insert( allGroups.end(), m_groupNodes.begin(), m_groupNodes.end() );
1004
1005 decSize += writeDataBlock( getGroupNodeModifierChain( "groups", allGroups ), decStream );
1006
1007 for( auto& mesh : m_meshes )
1008 {
1009 if( mesh->IsEmpty() )
1010 continue;
1011
1012 std::string meshName = "n_" + mesh->name;
1013
1014 std::string modelResourceName = "n_" + mesh->name;
1015 std::string matName = "m_" + mesh->name;
1016 std::string shaderName = "s_" + mesh->name;
1017 std::string modelModifierChainName = "n_" + mesh->name;
1018
1019 std::shared_ptr<DATA_BLOCK> block =
1020 getNodeModifierChain( meshName, mesh->name, mesh->parentName, modelResourceName, shaderName, matrix );
1021
1022 decSize += writeDataBlock( block, decStream );
1023
1024 block = getModelResourceModifierChain( modelModifierChainName, mesh.get(), meshName );
1025 decSize += writeDataBlock( block, decStream );
1026
1027 decSize += writeDataBlock( getLitTextureShaderBlock( shaderName, matName ), decStream );
1028
1029 decSize +=
1030 writeDataBlock( getMaterialResourceBlock( matName, mesh->diffuse_color, mesh->specular_color ), decStream );
1031
1032 block = getMeshContinuationBlock( mesh.get(), meshName );
1033 contSize += writeDataBlock( block, contStream );
1034 }
1035
1036 // finish it, we need the size totals above to generate the header
1037 writeDataBlock( getHeaderBlock( decSize, contSize ), outStream );
1038
1039 wxStreamBuffer* buffer = outStream.GetOutputStreamBuffer();
1040
1041 std::ofstream u3dFile( m_filename, std::ios::binary );
1042 if( !u3dFile.is_open() )
1043 {
1044 wxLogTrace( TRACE_MASK, wxString::Format( "Error opening file:%s", m_filename ) );
1045 return false;
1046 }
1047
1048 u3dFile.write( static_cast<const char*>( buffer->GetBufferStart() ), buffer->GetBufferSize() );
1049
1050 wxStreamBuffer* decBuffer = decStream.GetOutputStreamBuffer();
1051 u3dFile.write( static_cast<const char*>( decBuffer->GetBufferStart() ),
1052 decBuffer->GetBufferSize() );
1053
1054 wxStreamBuffer* contBuffer = contStream.GetOutputStreamBuffer();
1055 u3dFile.write( static_cast<const char*>( contBuffer->GetBufferStart() ),
1056 contBuffer->GetBufferSize() );
1057
1058 u3dFile.close();
1059
1060 return true;
1061}
const char * name
@ ADD
Definition am_param.h:150
This is an internal KiCad use attribute to add additional markup to a opencascade document for intern...
static const Standard_GUID & GetID()
Get the GUID of this attribute.
Implements the bit stream writer functionality.
void WriteF64(double aValue)
void WriteU8(uint8_t aValue)
void WriteU16(uint16_t uValue)
void WriteU32(uint32_t uValue)
std::shared_ptr< DATA_BLOCK > GetDataBlock()
void WriteDataBlock(std::shared_ptr< DATA_BLOCK > b)
void WriteF32(float fValue)
void WriteString(const std::string &aStr)
void WriteU64(uint64_t uValue)
void WriteCompressedU32(uint32_t aContext, uint32_t uValue)
static const uint32_t StaticFull
Contexts greater than this are static contexts.
Definition constants.h:57
std::vector< uint32_t > normalIndices
Coordinate indices, maps vertex normal positions to triangles.
Definition writer.h:102
std::vector< uint32_t > specularColorIndices
Coordinate indices, maps each vertex to a specular color.
Definition writer.h:112
std::vector< VECTOR3D > normals
Definition writer.h:74
std::vector< Graphic3d_Vec4 > diffuse_colors
List of all unique diffuse colors.
Definition writer.h:79
std::vector< uint32_t > coordIndices
Coordinate indices, maps vertex positions to triangles.
Definition writer.h:97
std::vector< uint32_t > diffuseColorIndices
Coordinate indices, maps each vertex to a diffuse color.
Definition writer.h:107
std::string name
The name of the mesh, this will be visible in U3D viewers.
Definition writer.h:127
std::vector< VECTOR3D > coords
Definition writer.h:72
std::vector< Graphic3d_Vec4 > specular_colors
List of all unique specular colors.
Definition writer.h:84
std::string m_filename
Definition writer.h:281
std::vector< GROUP_NODE > m_groupNodes
Definition writer.h:288
std::shared_ptr< DATA_BLOCK > getHeaderBlock(uint32_t aDeclSize, uint32_t aContSize)
Definition writer.cpp:674
std::shared_ptr< DATA_BLOCK > getShadingModifierBlock(const std::string &aShadingModName, const std::string &aShaderName)
Definition writer.cpp:587
std::shared_ptr< DATA_BLOCK > getLitTextureShaderBlock(const std::string &aShaderName, const std::string &aMaterialName)
Definition writer.cpp:694
void writeMatrix(BIT_STREAM_WRITER &aBitStreamWriter, const std::vector< float > &aMat)
Definition writer.cpp:534
bool Perform(const Handle(TDocStd_Document) &aDocument)
Definition writer.cpp:967
std::shared_ptr< DATA_BLOCK > getModelNodeBlock(const std::string &aModelNodeName, const std::string &aParentNodeName, const std::string &aModelResourceName, const std::vector< float > &aMat)
Definition writer.cpp:562
void getMeshName(const TDF_Label &label, Handle(XCAFDoc_ShapeTool) shapeTool, MESH *mesh)
Definition writer.cpp:249
WRITER(const std::string &aFilename)
Definition writer.cpp:524
const uint32_t m_contextBaseShadingID
Definition writer.h:285
std::shared_ptr< DATA_BLOCK > getMeshContinuationBlock(const MESH *aMesh, const std::string &aMeshName)
Definition writer.cpp:811
void generateMeshesByAssembly(const Handle(TDocStd_Document) &doc)
Definition writer.cpp:434
std::shared_ptr< DATA_BLOCK > getLightNodeBlock(const std::string &aLightNodeName, const std::string &aLightResourceName)
Definition writer.cpp:901
std::shared_ptr< DATA_BLOCK > getModelResourceModifierChain(const std::string &aModifierChainName, const MESH *aMesh, const std::string &aMeshname)
Definition writer.cpp:606
std::shared_ptr< DATA_BLOCK > getMaterialResourceBlock(const std::string &aMaterialName, const Graphic3d_Vec4 &aDiffuseColor, const Graphic3d_Vec3 &aSpecularColor)
Definition writer.cpp:718
std::shared_ptr< DATA_BLOCK > getGroupNodeModifierChain(const std::string &aModifierChainName, const std::vector< GROUP_NODE > &aGroupNodes)
Definition writer.cpp:627
std::vector< std::unique_ptr< MESH > > m_meshes
Definition writer.h:287
std::shared_ptr< DATA_BLOCK > getLightModifierChain(const std::string &aModifierChainName, const std::string &aLightResourceName)
Definition writer.cpp:882
void collectGeometryRecursive(const TDF_Label &label, const Handle(XCAFDoc_ShapeTool) &shapeTool, const Handle(XCAFDoc_ColorTool) &colorTool, const Handle(XCAFDoc_VisMaterialTool) &visMatTool, const gp_Trsf &cumulativeTransform, const std::string &baseName, std::unordered_map< Graphic3d_Vec4, MESH * > &meshesByColor)
Definition writer.cpp:289
std::shared_ptr< DATA_BLOCK > getLightResourceBlock(const std::string &aLightResourceName)
Definition writer.cpp:918
bool m_includeNormals
Definition writer.h:286
uint32_t writeDataBlock(std::shared_ptr< DATA_BLOCK > b, wxMemoryOutputStream &aStream)
Definition writer.cpp:940
std::map< std::string, int > m_meshDedupMap
Definition writer.h:284
std::shared_ptr< DATA_BLOCK > getNodeModifierChain(const std::string &aModifierChainName, const std::string &aModelNodeName, const std::string &aParentNodeName, const std::string &aModelResourceName, const std::string &aShaderName, const std::vector< float > &aMat)
Definition writer.cpp:650
std::shared_ptr< DATA_BLOCK > getGroupNodeBlock(const std::string &aGroupNodeName, const PARENT_NODE *aParentNode)
Definition writer.cpp:541
Bnd_Box m_meshBoundingBox
Definition writer.h:283
VECTOR3D m_center
Definition writer.h:282
std::shared_ptr< DATA_BLOCK > getMeshDeclarationBlock(const MESH *aMesh, const std::string &aMeshName)
Definition writer.cpp:751
#define _(s)
Handle(KICAD3D_INFO) KICAD3D_INFO
constexpr uint32_t LIGHTING_ENABLED
Definition writer.cpp:102
constexpr uint32_t USE_VERTEX_COLOR
Definition writer.cpp:104
constexpr uint32_t ALPHA_TEST_ENABLED
Definition writer.cpp:103
constexpr uint32_t EMISSIVE
Definition writer.cpp:113
constexpr uint32_t REFLECTIVITY
Definition writer.cpp:114
constexpr uint32_t DIFFUSE
Definition writer.cpp:111
constexpr uint32_t SPECULAR
Definition writer.cpp:112
constexpr uint32_t AMBIENT
Definition writer.cpp:110
constexpr uint32_t OPACITY
Definition writer.cpp:115
constexpr uint32_t LINE
Definition writer.cpp:94
constexpr uint32_t POINT
Definition writer.cpp:95
constexpr uint32_t GLYPH
Definition writer.cpp:96
constexpr uint32_t MESH
Definition writer.cpp:93
constexpr uint32_t MODIFIER_CHAIN
Definition data_block.h:31
constexpr uint32_t MESH_DECLARATION
Definition data_block.h:35
constexpr uint32_t MATERIAL_RESOURCE
Definition data_block.h:40
constexpr uint32_t MESH_CONTINUATION
Definition data_block.h:36
constexpr uint32_t LIGHT_NODE
Definition data_block.h:34
constexpr uint32_t GROUP_NODE
Definition data_block.h:32
constexpr uint32_t SHADING_MODIFIER
Definition data_block.h:37
constexpr uint32_t LIGHT_RESOURCE
Definition data_block.h:38
constexpr uint32_t MODEL_NODE
Definition data_block.h:33
constexpr uint32_t LIT_TEXTURE_SHADER
Definition data_block.h:39
constexpr uint32_t FILE_HEADER
Definition data_block.h:41
constexpr uint32_t DEFINED_UNITS
Definition data_block.h:46
std::vector< PARENT_NODE > parentNodes
List of parent nodes this group node belongs to.
Definition writer.h:199
std::string name
Name of this group node.
Definition writer.h:194
std::vector< float > mat
Transform matrix, 4x4, row major.
Definition writer.h:186
std::string name
Name of the parent node to link to.
Definition writer.h:181
VECTOR2I location
VECTOR3< double > VECTOR3D
Definition vector3.h:230
COLOR_BLEND_FUNCTION
Definition writer.cpp:83
#define TRACE_MASK
Definition writer.cpp:63
static bool isLabelABoardMesh(const TDF_Label &aLabel)
Definition writer.cpp:237
#define MODEL_PARENT_BOARD_NAME
Definition writer.cpp:65
static int colorFloatToDecimal(float aVal)
Definition writer.cpp:156
std::string getShapeName(TopAbs_ShapeEnum aShape)
Definition writer.cpp:137
static void printLabel(TDF_Label aLabel, Handle(XCAFDoc_ShapeTool) aShapeTool, Handle(XCAFDoc_ColorTool) aColorTool, const char *aPreMsg=nullptr)
Definition writer.cpp:173
static void dumpLabels(TDF_Label aLabel, Handle(XCAFDoc_ShapeTool) aShapeTool, Handle(XCAFDoc_ColorTool) aColorTool, int aDepth=0)
Dumps a label and the entire tree underneath it.
Definition writer.cpp:226
ALPHA_TEST_FUNCTION
Definition writer.cpp:70
#define MODEL_PARENT_COMPONENTS_NAME
Definition writer.cpp:66
static std::ostream & operator<<(std::ostream &aOStream, const Quantity_ColorRGBA &aColor)
Definition writer.cpp:162
static wxString getLabelName(const TDF_Label &aLabel)
Definition writer.cpp:119