Cogs.Core
DimeLoader.cpp
1#include "DimeLoader.h"
2
3#include "Foundation/Logging/Logger.h"
4
5#include "Resources/ResourceStore.h"
6#include "Resources/ModelManager.h"
7#include "Resources/MeshManager.h"
8#include "Resources/MaterialManager.h"
9#include "Resources/TextureManager.h"
10#include "Resources/DefaultMaterial.h"
11
12#include "Foundation/Platform/IO.h"
13
14#include <dime/Input.h>
15#include <dime/Output.h>
16#include <dime/Model.h>
17#include <dime/State.h>
18#include <dime/convert/convert.h>
19#include <dime/convert/layerdata.h>
20#include <dime/convert/layergroup.h>
21
22namespace
23{
24 Cogs::Logging::Log logger = Cogs::Logging::getLogger("DimeLoader");
25}
26
27bool Cogs::Core::DimeLoader::canLoad(Context *, const ModelLoadInfo & loadInfo)
28{
29 auto extension = IO::extension(loadInfo.resourcePath);
30 return extension == ".dxf";
31}
32
33namespace Cogs
34{
35 namespace Core
36 {
37 MaterialInstanceHandle createMaterial(Context * context, int colorIndex, PrimitiveType::EPrimitiveType primitiveType)
38 {
39 auto materialInstanceHandle = context->materialInstanceManager->createMaterialInstance(context->materialManager->getDefaultMaterial());
40 {
41 dxfdouble r, g, b;
42 dimeLayer::colorToRGB(colorIndex, r, g, b);
43
44 auto materialInstance = materialInstanceHandle.resolve();
45 materialInstance->setVariant("LightModel", "BaseColor");
46 materialInstance->setVec4Property(DefaultMaterial::DiffuseColor, glm::vec4(r, g, b, 1));
47 materialInstance->setVec4Property(DefaultMaterial::SpecularColor, glm::vec4(0, 0, 0, 0));
48 materialInstance->setBoolProperty(DefaultMaterial::EnableLighting, false);
49 materialInstance->setFloatProperty(DefaultMaterial::LineWidth, 1.0f);
50 materialInstance->setPermutation(primitiveType == PrimitiveType::LineList ? "Line" : "Default");
51 materialInstance->options.cullMode = CullMode::None;
52 }
53
54 return materialInstanceHandle;
55 }
56
57 void createLayerModel(Context * context,
58 Model & model,
59 uint32_t parentIndex,
60 const std::string& name,
61 const std::vector<PositionNormalVertex>& vertexBuffer,
62 const std::vector<uint32_t>& indexBuffer,
63 PrimitiveType::EPrimitiveType primitiveType,
64 int colorIndex)
65 {
66 auto mesh = context->meshManager->createLocked();
67 mesh->setName(name);
68 mesh->setVertexData(vertexBuffer.data(), vertexBuffer.size());
69 mesh->setIndexes(std::move(indexBuffer));
70 mesh->primitiveType = primitiveType;
71 mesh->setBounds(calculateBounds(&(*mesh)));
72
73 auto & modelPart = model.parts.emplace_back();
74 modelPart.parentIndex = parentIndex;
75 model.setPartName(modelPart, name);
76 model.setPartTransform(modelPart, glm::mat4(1.0f));
77 modelPart.meshIndex = (uint32_t)model.meshes.size();
78 model.meshes.emplace_back(mesh.getHandle());
79 modelPart.materialIndex = (uint32_t)model.materials.size();
80 auto material = createMaterial(context, colorIndex, primitiveType);
81 model.materials.emplace_back(material);
82 }
83 }
84}
85
86bool Cogs::Core::DimeLoader::load(Context * context, const ModelLoadInfo & loadInfo)
87{
88 std::string data = context->resourceStore->getResourceContentString(loadInfo.resourcePath);
89
90 dimeInput in;
91 if (!in.setMemoryBuffer(data))
92 {
93 LOG_ERROR(logger, "Error opening file for reading: %s", loadInfo.resourcePath.c_str());
94 return false;
95 }
96
97 dimeModel dimeModel;
98 if (!dimeModel.read(&in))
99 {
100 LOG_ERROR(logger, "DXF read error in line: %d", in.getFilePosition());
101 return false;
102 }
103
104 dxfConverter converter;
105 converter.setMaxerr(0.1f);
106 auto useDepthOffset = (loadInfo.modelFlags & ModelLoadFlags::CustomExtensionFlag) != ModelLoadFlags::None;
107 if (!converter.doConvert(dimeModel, useDepthOffset))
108 {
109 LOG_ERROR(logger, "Error during conversion: %s", loadInfo.resourcePath.c_str());
110 return false;
111 }
112
113 auto model = context->modelManager->lock(loadInfo.handle);
114
115 const auto& allLayers = converter.getAllLayers();
116 for (auto& itLayers : allLayers)
117 {
118 const auto& layerGroupName = itLayers.first;
119 const auto* layerGroup = itLayers.second;
120 assert(layerGroup);
121
122 uint32_t index = (uint32_t)model->parts.size();
123 auto & modelPart = model->parts.emplace_back();
124 modelPart.parentIndex = (uint32_t)-1;
125 model->setPartName(modelPart, layerGroupName);
126
127 const auto& allColorLayers = layerGroup->getAllLayerData();
128 for (auto& itLayerData : allColorLayers)
129 {
130 const auto layerColorIndex = itLayerData.first;
131 const auto* layer = itLayerData.second;
132 assert(layer);
133
134 auto& lineIndices = layer->lineindices;
135 auto& linePoints = layer->linebsp;
136 auto numLineIndices = lineIndices.count();
137 auto numLinePoints = linePoints.numPoints();
138 if (numLineIndices > 0 || numLinePoints > 0)
139 {
140 std::vector<PositionNormalVertex> vertexes(numLinePoints);
141 for (int i = 0; i < numLinePoints; i++)
142 {
143 dimeVec3f dimePoint;
144 linePoints.getPoint(i, dimePoint);
145
146 auto& v = vertexes[i];
147 v.position = glm::vec3(dimePoint.x, dimePoint.z, dimePoint.y);
148 v.normal = glm::vec3(0, 0, 1);
149 }
150
151 std::vector<uint32_t> indexes;
152 auto prevIndex = -1;
153 for (auto i = 0; i < lineIndices.count(); i++)
154 {
155 auto currentIndex = lineIndices[i];
156 if (currentIndex != -1 && prevIndex != -1)
157 {
158 indexes.push_back(prevIndex);
159 indexes.push_back(currentIndex);
160 }
161
162 prevIndex = currentIndex;
163 }
164
165 createLayerModel(context, *model, index, "lines " + std::to_string(layerColorIndex), vertexes, indexes, PrimitiveType::LineList, layerColorIndex);
166 }
167
168 auto& faceIndices = layer->faceindices;
169 auto& facePoints = layer->facebsp;
170 auto numFaceIndices = faceIndices.count();
171 auto numFacePoints = facePoints.numPoints();
172 if (numFacePoints > 0 && numFaceIndices > 0)
173 {
174 std::vector<PositionNormalVertex> vertexes(numFacePoints);
175 for (int i = 0; i < numFacePoints; i++)
176 {
177 dimeVec3f dimePoint;
178 facePoints.getPoint(i, dimePoint);
179
180 auto& v = vertexes[i];
181 v.position = glm::vec3(dimePoint.x, dimePoint.z, dimePoint.y);
182 v.normal = glm::vec3(0, 0, 1);
183 }
184
185 std::vector<uint32_t> indexes;
186 std::vector<uint32_t> temp;
187 for (auto i = 0; i < faceIndices.count(); i++)
188 {
189 auto currentIndex = faceIndices[i];
190 if (currentIndex == -1 && !temp.empty())
191 {
192 if (temp.size() == 3 || temp.size() == 4)
193 {
194 indexes.push_back(temp[0]);
195 indexes.push_back(temp[1]);
196 indexes.push_back(temp[2]);
197 }
198
199 if (temp.size() == 4)
200 {
201 indexes.push_back(temp[0]);
202 indexes.push_back(temp[2]);
203 indexes.push_back(temp[3]);
204 }
205
206 if (temp.size() == 3 && temp.size() == 4)
207 {
208 LOG_WARNING(logger, "Unknown polygon type in the DXF file: %s", loadInfo.resourcePath.c_str());
209 }
210
211 temp.clear();
212 }
213 else
214 {
215 temp.push_back(currentIndex);
216 }
217 }
218
219 createLayerModel(context, *model, index, "triangles " + std::to_string(layerColorIndex), vertexes, indexes, PrimitiveType::TriangleList, layerColorIndex);
220 }
221 }
222 }
223
224 return true;
225}
Log implementation class.
Definition: LogManager.h:139
@ CustomExtensionFlag
Custom flag that can be used by an extension loader.
Cogs::Geometry::BoundingBox COGSCORE_DLL_API calculateBounds(Mesh *mesh)
Calculate a bounding box for the given mesh.
Definition: MeshHelper.cpp:283
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
@ LineList
List of lines.
Definition: Common.h:120
@ TriangleList
List of triangles.
Definition: Common.h:116