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