FreeCAD

Форк
0
/
MaterialConfigLoader.cpp 
1103 строки · 48.1 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2023 David Carter <dcarter@david.carter.ca>             *
3
 *                                                                         *
4
 *   This file is part of FreeCAD.                                         *
5
 *                                                                         *
6
 *   FreeCAD is free software: you can redistribute it and/or modify it    *
7
 *   under the terms of the GNU Lesser General Public License as           *
8
 *   published by the Free Software Foundation, either version 2.1 of the  *
9
 *   License, or (at your option) any later version.                       *
10
 *                                                                         *
11
 *   FreeCAD is distributed in the hope that it will be useful, but        *
12
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      *
14
 *   Lesser General Public License for more details.                       *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Lesser General Public      *
17
 *   License along with FreeCAD. If not, see                               *
18
 *   <https://www.gnu.org/licenses/>.                                      *
19
 *                                                                         *
20
 **************************************************************************/
21

22
#include "PreCompiled.h"
23
#ifndef _PreComp_
24
#include <QDirIterator>
25
#include <QFileInfo>
26
#include <QString>
27
#include <QFile>
28
#include <QIODevice>
29
#include <QTextStream>
30
#include <QUuid>
31
#include <memory>
32
#include <fstream>
33
#endif
34

35

36
#include <App/Application.h>
37
#include <Base/Interpreter.h>
38

39

40
#include "Exceptions.h"
41
#include "MaterialConfigLoader.h"
42
#include "MaterialLoader.h"
43
#include "Model.h"
44
#include "ModelUuids.h"
45

46

47
using namespace Materials;
48

49
bool MaterialConfigLoader::isConfigStyle(const QString& path)
50
{
51
    QSettings fcmat(path, QSettings::IniFormat);
52

53
    // No [sections] means not .ini
54
    if (fcmat.childGroups().empty()) {
55
        return false;
56
    }
57

58
    // Sometimes arrays can create a false positive
59
    QFile infile(path);
60
    if (infile.open(QIODevice::ReadOnly)) {
61
        QTextStream in(&infile);
62

63
        if (!in.atEnd()) {
64
            auto line = in.readLine();
65
            if (line.trimmed().startsWith(QLatin1Char('-'))
66
                || line.trimmed().startsWith(QLatin1Char('#'))) {
67
                // Definitely a YAML file
68
                return false;
69
            }
70
        }
71
    }
72
    infile.close();
73

74
    // No false positive
75
    return true;
76
}
77

78
bool MaterialConfigLoader::readFile(const QString& path, QMap<QString, QString>& map)
79
{
80
    // This function is necessary as the built in routines don't always return the full value string
81
    QFile infile(path);
82
    if (infile.open(QIODevice::ReadOnly)) {
83
        QTextStream in(&infile);
84
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
85
        in.setCodec("UTF-8");
86
#endif
87
        QString line;
88
        QString prefix;
89
        while (!in.atEnd()) {
90
            line = in.readLine();
91
            if (line.trimmed().startsWith(QLatin1Char(';'))) {
92
                continue;
93
            }
94

95
            if (line.startsWith(QLatin1Char('['))) {
96
                // read prefix
97
                auto end = line.indexOf(QLatin1Char(']'));
98
                if (end > 1) {
99
                    prefix = line.mid(1, end - 1) + QString::fromStdString("/");
100

101
                    // Render WB uses both Render and Rendering
102
                    if (prefix == QString::fromStdString("Rendering/")) {
103
                        prefix = QString::fromStdString("Render/");
104
                    }
105
                }
106
            }
107
            else {
108
                auto separator = line.indexOf(QLatin1Char('='));
109
                if (separator > 2) {
110
                    auto left = line.mid(0, separator - 1);
111
                    auto right = line.mid(separator + 2);
112
                    map[prefix + left] = right;
113
                }
114
            }
115
        }
116
        infile.close();
117
        return true;
118
    }
119

120
    return false;
121
}
122

123
void MaterialConfigLoader::splitTexture(const QString& value, QString* texture, QString* remain)
124
{
125
    // Split Texture(...);(...) into its two pieces
126
    if (value.contains(QLatin1Char(';'))) {
127
        auto separator = value.indexOf(QLatin1Char(';'));
128
        auto left = value.mid(0, separator);
129
        auto right = value.mid(separator + 1);
130
        if (isTexture(left)) {
131
            *texture = left;
132
            *remain = right;
133
        }
134
        else {
135
            *texture = right;
136
            *remain = left;
137
        }
138
    }
139
    else {
140
        if (isTexture(value)) {
141
            *texture = value;
142
        }
143
        else {
144
            *remain = value;
145
        }
146
    }
147
}
148

149
void MaterialConfigLoader::splitTextureObject(const QString& value,
150
                                              QString* texture,
151
                                              QString* remain,
152
                                              QString* object)
153
{
154
    splitTexture(value, texture, remain);
155
    if (*remain == QString::fromStdString("Object")) {
156
        *remain = QString();  // Empty string
157
        *object = QString::fromStdString("true");
158
    }
159
}
160

161
QString MaterialConfigLoader::getAuthorAndLicense(const QString& path)
162
{
163
    std::ifstream infile(path.toStdString());
164
    QString noAuthor;
165

166
    // Skip the first line
167
    std::string line;
168
    if (!std::getline(infile, line)) {
169
        return noAuthor;
170
    }
171

172
    // The second line has it in a comment
173
    if (!std::getline(infile, line)) {
174
        return noAuthor;
175
    }
176
    std::size_t found = line.find(';');
177
    if (found != std::string::npos) {
178
        return QString::fromStdString(trim_copy(line.substr(found + 1)));
179
    }
180

181
    return noAuthor;
182
}
183

184
void MaterialConfigLoader::addVectorRendering(const QMap<QString, QString>& fcmat,
185
                                              const std::shared_ptr<Material>& finalModel)
186
{
187
    QString sectionFillPattern = value(fcmat, "VectorRendering/SectionFillPattern", "");
188
    QString sectionLinewidth = value(fcmat, "VectorRendering/SectionLinewidth", "");
189
    QString sectionColor = value(fcmat, "VectorRendering/SectionColor", "");
190
    QString viewColor = value(fcmat, "VectorRendering/ViewColor", "");
191
    QString viewFillPattern = value(fcmat, "VectorRendering/ViewFillPattern", "");
192
    QString viewLinewidth = value(fcmat, "VectorRendering/ViewLinewidth", "");
193

194
    // Defined by the Render WB
195
    QString aSection = value(fcmat, "Architectural/SectionColor", "");
196

197
    if (!aSection.isEmpty()) {
198
        sectionColor = aSection;
199
    }
200

201
    if (sectionFillPattern.length() + sectionLinewidth.length() + sectionColor.length()
202
            + viewColor.length() + viewFillPattern.length() + viewLinewidth.length()
203
        > 0) {
204
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Vector);
205

206
        // Now add the data
207
        setAppearanceValue(finalModel, "SectionFillPattern", sectionFillPattern);
208
        setAppearanceValue(finalModel, "SectionLinewidth", sectionLinewidth);
209
        setAppearanceValue(finalModel, "SectionColor", sectionColor);
210
        setAppearanceValue(finalModel, "ViewColor", viewColor);
211
        setAppearanceValue(finalModel, "ViewFillPattern", viewFillPattern);
212
        setAppearanceValue(finalModel, "ViewLinewidth", viewLinewidth);
213
    }
214
}
215

216
void MaterialConfigLoader::addRendering(const QMap<QString, QString>& fcmat,
217
                                        const std::shared_ptr<Material>& finalModel)
218
{
219
    QString ambientColor = value(fcmat, "Rendering/AmbientColor", "");
220
    QString diffuseColor = value(fcmat, "Rendering/DiffuseColor", "");
221
    QString emissiveColor = value(fcmat, "Rendering/EmissiveColor", "");
222
    QString shininess = value(fcmat, "Rendering/Shininess", "");
223
    QString specularColor = value(fcmat, "Rendering/SpecularColor", "");
224
    QString transparency = value(fcmat, "Rendering/Transparency", "");
225
    QString texturePath = value(fcmat, "Rendering/TexturePath", "");
226
    QString textureScaling = value(fcmat, "Rendering/TextureScaling", "");
227
    QString fragmentShader = value(fcmat, "Rendering/FragmentShader", "");
228
    QString vertexShader = value(fcmat, "Rendering/VertexShader", "");
229

230
    // Defined by the Render WB
231
    QString aDiffuse = value(fcmat, "Architectural/DiffuseColor", "");
232
    QString aTransparency = value(fcmat, "Architectural/Transparency", "");
233

234
    if (!aDiffuse.isEmpty()) {
235
        diffuseColor = aDiffuse;
236
    }
237
    if (!aTransparency.isEmpty()) {
238
        transparency = aTransparency;
239
    }
240

241
    // Check which model we need
242
    bool useTexture = false;
243
    bool useAdvanced = false;
244
    bool useBasic = false;
245
    if (texturePath.length() + textureScaling.length() > 0) {
246
        useTexture = true;
247
    }
248
    if (fragmentShader.length() + vertexShader.length() > 0) {
249
        useAdvanced = true;
250
    }
251
    if (ambientColor.length() + diffuseColor.length() + emissiveColor.length() + shininess.length()
252
            + specularColor.length() + transparency.length()
253
        > 0) {
254
        useBasic = true;
255
    }
256

257
    if (useAdvanced) {
258
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Advanced);
259
    }
260
    else if (useTexture) {
261
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Texture);
262
    }
263
    else if (useBasic) {
264
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Basic);
265
    }
266

267
    // Now add the data
268
    setAppearanceValue(finalModel, "AmbientColor", ambientColor);
269
    setAppearanceValue(finalModel, "DiffuseColor", diffuseColor);
270
    setAppearanceValue(finalModel, "EmissiveColor", emissiveColor);
271
    setAppearanceValue(finalModel, "Shininess", shininess);
272
    setAppearanceValue(finalModel, "SpecularColor", specularColor);
273
    setAppearanceValue(finalModel, "Transparency", transparency);
274
    setAppearanceValue(finalModel, "TexturePath", texturePath);
275
    setAppearanceValue(finalModel, "TextureScaling", textureScaling);
276
    setAppearanceValue(finalModel, "FragmentShader", fragmentShader);
277
    setAppearanceValue(finalModel, "VertexShader", vertexShader);
278
}
279

280
QString MaterialConfigLoader::multiLineKey(QMap<QString, QString>& fcmat, const QString& prefix)
281
{
282
    // fcmat.beginGroup(QString::fromStdString("Render"));
283
    QString multiLineString;
284
    auto keys = fcmat.keys();
285
    for (const auto& key : keys) {
286
        if (key.startsWith(prefix) || key.startsWith(QString::fromStdString("Render/") + prefix)) {
287
            QString string = value(fcmat, key.toStdString(), "");
288
            if (multiLineString.isEmpty()) {
289
                multiLineString += string;
290
            }
291
            else {
292
                multiLineString += QString::fromStdString("\n") + string;
293
            }
294
        }
295
    }
296
    // fcmat.endGroup();
297

298
    return multiLineString;
299
}
300

301
void MaterialConfigLoader::addRenderAppleseed(QMap<QString, QString>& fcmat,
302
                                              const std::shared_ptr<Material>& finalModel)
303
{
304
    QString prefix = QString::fromStdString("Render.Appleseed");
305
    QString string = multiLineKey(fcmat, prefix);
306

307
    if (!string.isEmpty()) {
308
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Appleseed);
309

310
        // Now add the data
311
        setAppearanceValue(finalModel, "Render.Appleseed", string);
312
    }
313
}
314

315
void MaterialConfigLoader::addRenderCarpaint(QMap<QString, QString>& fcmat,
316
                                             const std::shared_ptr<Material>& finalModel)
317
{
318
    QString renderBaseColorValue = value(fcmat, "Render/Render.Carpaint.BaseColor", "");
319
    QString renderBump = value(fcmat, "Render/Render.Carpaint.Bump", "");
320
    QString renderDisplacement = value(fcmat, "Render/Render.Carpaint.Displacement", "");
321
    QString renderNormal = value(fcmat, "Render/Render.Carpaint.Normal", "");
322

323
    // Split out the textures
324
    QString renderBaseColor;
325
    QString renderBaseColorTexture;
326
    QString renderBaseColorObject;
327
    splitTextureObject(renderBaseColorValue,
328
                       &renderBaseColorTexture,
329
                       &renderBaseColor,
330
                       &renderBaseColorObject);
331

332
    if (!renderBaseColorValue.isEmpty() || !renderBump.isEmpty() || !renderDisplacement.isEmpty()
333
        || !renderNormal.isEmpty()) {
334
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Carpaint);
335

336
        // Now add the data
337
        setAppearanceValue(finalModel, "Render.Carpaint.BaseColor", renderBaseColor);
338
        setAppearanceValue(finalModel, "Render.Carpaint.BaseColor.Texture", renderBaseColorTexture);
339
        setAppearanceValue(finalModel, "Render.Carpaint.BaseColor.Object", renderBaseColorObject);
340
        setAppearanceValue(finalModel, "Render.Carpaint.Bump", renderBump);
341
        setAppearanceValue(finalModel, "Render.Carpaint.Displacement", renderDisplacement);
342
        setAppearanceValue(finalModel, "Render.Carpaint.Normal", renderNormal);
343
    }
344
}
345

346
void MaterialConfigLoader::addRenderCycles(QMap<QString, QString>& fcmat,
347
                                           const std::shared_ptr<Material>& finalModel)
348
{
349
    QString prefix = QString::fromStdString("Render.Cycles");
350
    QString string = multiLineKey(fcmat, prefix);
351
    if (!string.isEmpty()) {
352
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Cycles);
353

354
        // Now add the data
355
        setAppearanceValue(finalModel, "Render.Cycles", string);
356
    }
357
}
358

359
void MaterialConfigLoader::addRenderDiffuse(QMap<QString, QString>& fcmat,
360
                                            const std::shared_ptr<Material>& finalModel)
361
{
362
    QString renderBump = value(fcmat, "Render/Render.Diffuse.Bump", "");
363
    QString renderColorValue = value(fcmat, "Render/Render.Diffuse.Color", "");
364
    QString renderDisplacement = value(fcmat, "Render/Render.Diffuse.Displacement", "");
365
    QString renderNormal = value(fcmat, "Render/Render.Diffuse.Normal", "");
366

367
    // Split out the textures
368
    QString renderColor;
369
    QString renderColorTexture;
370
    QString renderColorObject;
371
    splitTextureObject(renderColorValue, &renderColorTexture, &renderColor, &renderColorObject);
372

373
    if (!renderBump.isEmpty() || !renderColorValue.isEmpty() || !renderDisplacement.isEmpty()
374
        || !renderNormal.isEmpty()) {
375
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Diffuse);
376

377
        // Now add the data
378
        setAppearanceValue(finalModel, "Render.Diffuse.Bump", renderBump);
379
        setAppearanceValue(finalModel, "Render.Diffuse.Color", renderColor);
380
        setAppearanceValue(finalModel, "Render.Diffuse.Color.Texture", renderColorTexture);
381
        setAppearanceValue(finalModel, "Render.Diffuse.Color.Object", renderColorObject);
382
        setAppearanceValue(finalModel, "Render.Diffuse.Displacement", renderDisplacement);
383
        setAppearanceValue(finalModel, "Render.Diffuse.Normal", renderNormal);
384
    }
385
}
386

387
void MaterialConfigLoader::addRenderDisney(QMap<QString, QString>& fcmat,
388
                                           const std::shared_ptr<Material>& finalModel)
389
{
390
    QString renderAnisotropicValue = value(fcmat, "Render/Render.Disney.Anisotropic", "");
391
    QString renderBaseColorValue = value(fcmat, "Render/Render.Disney.BaseColor", "");
392
    QString renderBump = value(fcmat, "Render/Render.Disney.Bump", "");
393
    QString renderClearCoatValue = value(fcmat, "Render/Render.Disney.ClearCoat", "");
394
    QString renderClearCoatGlossValue = value(fcmat, "Render/Render.Disney.ClearCoatGloss", "");
395
    QString renderDisplacement = value(fcmat, "Render/Render.Disney.Displacement", "");
396
    QString renderMetallicValue = value(fcmat, "Render/Render.Disney.Metallic", "");
397
    QString renderNormal = value(fcmat, "Render/Render.Disney.Normal", "");
398
    QString renderRoughnessValue = value(fcmat, "Render/Render.Disney.Roughness", "");
399
    QString renderSheenValue = value(fcmat, "Render/Render.Disney.Sheen", "");
400
    QString renderSheenTintValue = value(fcmat, "Render/Render.Disney.SheenTint", "");
401
    QString renderSpecularValue = value(fcmat, "Render/Render.Disney.Specular", "");
402
    QString renderSpecularTintValue = value(fcmat, "Render/Render.Disney.SpecularTint", "");
403
    QString renderSubsurfaceValue = value(fcmat, "Render/Render.Disney.Subsurface", "");
404

405
    // Split out the textures
406
    QString renderAnisotropic;
407
    QString renderAnisotropicTexture;
408
    splitTexture(renderAnisotropicValue, &renderAnisotropicTexture, &renderAnisotropic);
409
    QString renderBaseColor;
410
    QString renderBaseColorTexture;
411
    QString renderBaseColorObject;
412
    splitTextureObject(renderBaseColorValue,
413
                       &renderBaseColorTexture,
414
                       &renderBaseColor,
415
                       &renderBaseColorObject);
416
    QString renderClearCoat;
417
    QString renderClearCoatTexture;
418
    QString renderClearCoatObject;
419
    splitTextureObject(renderClearCoatValue,
420
                       &renderClearCoatTexture,
421
                       &renderClearCoat,
422
                       &renderClearCoatObject);
423
    QString renderClearCoatGloss;
424
    QString renderClearCoatGlossTexture;
425
    QString renderClearCoatGlossObject;
426
    splitTextureObject(renderClearCoatGlossValue,
427
                       &renderClearCoatGlossTexture,
428
                       &renderClearCoatGloss,
429
                       &renderClearCoatGlossObject);
430
    QString renderMetallic;
431
    QString renderMetallicTexture;
432
    splitTexture(renderMetallicValue, &renderMetallicTexture, &renderMetallic);
433
    QString renderRoughness;
434
    QString renderRoughnessTexture;
435
    splitTexture(renderRoughnessValue, &renderRoughnessTexture, &renderRoughness);
436
    QString renderSheen;
437
    QString renderSheenTexture;
438
    splitTexture(renderSheenValue, &renderSheenTexture, &renderSheen);
439
    QString renderSheenTint;
440
    QString renderSheenTintTexture;
441
    splitTexture(renderSheenTintValue, &renderSheenTintTexture, &renderSheenTint);
442
    QString renderSpecular;
443
    QString renderSpecularTexture;
444
    QString renderSpecularObject;
445
    splitTextureObject(renderSpecularValue,
446
                       &renderSpecularTexture,
447
                       &renderSpecular,
448
                       &renderSpecularObject);
449
    QString renderSpecularTint;
450
    QString renderSpecularTintTexture;
451
    QString renderSpecularTintObject;
452
    splitTextureObject(renderSpecularTintValue,
453
                       &renderSpecularTintTexture,
454
                       &renderSpecularTint,
455
                       &renderSpecularTintObject);
456
    QString renderSubsurface;
457
    QString renderSubsurfaceTexture;
458
    splitTexture(renderSubsurfaceValue, &renderSubsurfaceTexture, &renderSubsurface);
459

460
    if (!renderAnisotropicValue.isEmpty() || !renderBaseColorValue.isEmpty()
461
        || !renderBump.isEmpty() || !renderClearCoatValue.isEmpty()
462
        || !renderClearCoatGlossValue.isEmpty() || !renderDisplacement.isEmpty()
463
        || !renderMetallicValue.isEmpty() || !renderNormal.isEmpty()
464
        || !renderRoughnessValue.isEmpty() || !renderSheenValue.isEmpty()
465
        || !renderSheenTintValue.isEmpty() || !renderSpecularValue.isEmpty()
466
        || !renderSpecularTintValue.isEmpty() || !renderSubsurfaceValue.isEmpty()) {
467
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Disney);
468

469
        // Now add the data
470
        setAppearanceValue(finalModel, "Render.Disney.Anisotropic", renderAnisotropic);
471
        setAppearanceValue(finalModel,
472
                           "Render.Disney.Anisotropic.Texture",
473
                           renderAnisotropicTexture);
474
        setAppearanceValue(finalModel, "Render.Disney.BaseColor", renderBaseColor);
475
        setAppearanceValue(finalModel, "Render.Disney.BaseColor.Texture", renderBaseColorTexture);
476
        setAppearanceValue(finalModel, "Render.Disney.Bump", renderBump);
477
        setAppearanceValue(finalModel, "Render.Disney.ClearCoat", renderClearCoat);
478
        setAppearanceValue(finalModel, "Render.Disney.ClearCoat.Texture", renderClearCoatTexture);
479
        setAppearanceValue(finalModel, "Render.Disney.ClearCoatGloss", renderClearCoatGloss);
480
        setAppearanceValue(finalModel,
481
                           "Render.Disney.ClearCoatGloss.Texture",
482
                           renderClearCoatGlossTexture);
483
        setAppearanceValue(finalModel, "Render.Disney.Displacement", renderDisplacement);
484
        setAppearanceValue(finalModel, "Render.Disney.Metallic", renderMetallic);
485
        setAppearanceValue(finalModel, "Render.Disney.Metallic.Texture", renderMetallicTexture);
486
        setAppearanceValue(finalModel, "Render.Disney.Normal", renderNormal);
487
        setAppearanceValue(finalModel, "Render.Disney.Roughness", renderRoughness);
488
        setAppearanceValue(finalModel, "Render.Disney.Roughness.Texture", renderRoughnessTexture);
489
        setAppearanceValue(finalModel, "Render.Disney.Sheen", renderSheen);
490
        setAppearanceValue(finalModel, "Render.Disney.Sheen.Texture", renderSheenTexture);
491
        setAppearanceValue(finalModel, "Render.Disney.SheenTint", renderSheenTint);
492
        setAppearanceValue(finalModel, "Render.Disney.SheenTint.Texture", renderSheenTintTexture);
493
        setAppearanceValue(finalModel, "Render.Disney.Specular", renderSpecular);
494
        setAppearanceValue(finalModel, "Render.Disney.Specular.Texture", renderSpecularTexture);
495
        setAppearanceValue(finalModel, "Render.Disney.SpecularTint", renderSpecularTint);
496
        setAppearanceValue(finalModel,
497
                           "Render.Disney.SpecularTint.Texture",
498
                           renderSpecularTintTexture);
499
        setAppearanceValue(finalModel, "Render.Disney.Subsurface", renderSubsurface);
500
        setAppearanceValue(finalModel, "Render.Disney.Subsurface.Texture", renderSubsurfaceTexture);
501
    }
502
}
503

504
void MaterialConfigLoader::addRenderEmission(QMap<QString, QString>& fcmat,
505
                                             const std::shared_ptr<Material>& finalModel)
506
{
507
    QString renderBump = value(fcmat, "Render/Render.Emission.Bump", "");
508
    QString renderColorValue = value(fcmat, "Render/Render.Emission.Color", "");
509
    QString renderNormal = value(fcmat, "Render/Render.Emission.Normal", "");
510
    QString renderPowerValue = value(fcmat, "Render/Render.Emission.Power", "");
511

512
    // Split out the textures
513
    QString renderColor;
514
    QString renderColorTexture;
515
    QString renderColorObject;
516
    splitTextureObject(renderColorValue, &renderColorTexture, &renderColor, &renderColorObject);
517
    QString renderPower;
518
    QString renderPowerTexture;
519
    splitTexture(renderPowerValue, &renderPowerTexture, &renderPower);
520

521
    if (!renderColorValue.isEmpty() || !renderBump.isEmpty() || !renderPowerValue.isEmpty()
522
        || !renderNormal.isEmpty()) {
523
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Emission);
524

525
        // Now add the data
526
        setAppearanceValue(finalModel, "Render.Emission.Bump", renderBump);
527
        setAppearanceValue(finalModel, "Render.Emission.Color", renderColor);
528
        setAppearanceValue(finalModel, "Render.Emission.Color.Texture", renderColorTexture);
529
        setAppearanceValue(finalModel, "Render.Emission.Color.Object", renderColorObject);
530
        setAppearanceValue(finalModel, "Render.Emission.Normal", renderNormal);
531
        setAppearanceValue(finalModel, "Render.Emission.Power", renderPower);
532
        setAppearanceValue(finalModel, "Render.Emission.Power.Texture", renderPowerTexture);
533
    }
534
}
535

536
void MaterialConfigLoader::addRenderGlass(QMap<QString, QString>& fcmat,
537
                                          const std::shared_ptr<Material>& finalModel)
538
{
539
    QString renderBump = value(fcmat, "Render/Render.Glass.Bump", "");
540
    QString renderColorValue = value(fcmat, "Render/Render.Glass.Color", "");
541
    QString renderIORValue = value(fcmat, "Render/Render.Glass.IOR", "");
542
    QString renderDisplacement = value(fcmat, "Render/Render.Glass.Displacement", "");
543
    QString renderNormal = value(fcmat, "Render/Render.Glass.Normal", "");
544

545
    // Split out the textures
546
    QString renderColor;
547
    QString renderColorTexture;
548
    QString renderColorObject;
549
    splitTextureObject(renderColorValue, &renderColorTexture, &renderColor, &renderColorObject);
550
    QString renderIOR;
551
    QString renderIORTexture;
552
    splitTexture(renderIORValue, &renderIORTexture, &renderIOR);
553

554
    if (!renderBump.isEmpty() || !renderColorValue.isEmpty() || !renderIORValue.isEmpty()
555
        || !renderDisplacement.isEmpty() || !renderNormal.isEmpty()) {
556
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Glass);
557

558
        setAppearanceValue(finalModel, "Render.Glass.Bump", renderBump);
559
        setAppearanceValue(finalModel, "Render.Glass.Color", renderColor);
560
        setAppearanceValue(finalModel, "Render.Glass.Color.Texture", renderColorTexture);
561
        setAppearanceValue(finalModel, "Render.Glass.Color.Object", renderColorObject);
562
        setAppearanceValue(finalModel, "Render.Glass.IOR", renderIOR);
563
        setAppearanceValue(finalModel, "Render.Glass.IOR.Texture", renderIORTexture);
564
        setAppearanceValue(finalModel, "Render.Glass.Displacement", renderDisplacement);
565
        setAppearanceValue(finalModel, "Render.Glass.Normal", renderNormal);
566
    }
567
}
568

569
void MaterialConfigLoader::addRenderLuxcore(QMap<QString, QString>& fcmat,
570
                                            const std::shared_ptr<Material>& finalModel)
571
{
572
    QString prefix = QString::fromStdString("Render.Luxcore");
573
    QString string = multiLineKey(fcmat, prefix);
574

575
    if (!string.isEmpty()) {
576
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Luxcore);
577

578
        // Now add the data
579
        setAppearanceValue(finalModel, "Render.Luxcore", string);
580
    }
581
}
582

583
void MaterialConfigLoader::addRenderLuxrender(QMap<QString, QString>& fcmat,
584
                                              const std::shared_ptr<Material>& finalModel)
585
{
586
    QString prefix = QString::fromStdString("Render.Luxrender");
587
    QString string = multiLineKey(fcmat, prefix);
588

589
    if (!string.isEmpty()) {
590
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Luxrender);
591

592
        // Now add the data
593
        setAppearanceValue(finalModel, "Render.Luxrender", string);
594
    }
595
}
596

597
void MaterialConfigLoader::addRenderMixed(QMap<QString, QString>& fcmat,
598
                                          const std::shared_ptr<Material>& finalModel)
599
{
600
    QString renderBump = value(fcmat, "Render/Render.Mixed.Bump", "");
601
    QString renderDiffuseColorValue = value(fcmat, "Render/Render.Mixed.Diffuse.Color", "");
602
    QString renderDisplacement = value(fcmat, "Render/Render.Mixed.Displacement", "");
603
    QString renderGlassColorValue = value(fcmat, "Render/Render.Mixed.Glass.Color", "");
604
    QString renderGlassIORValue = value(fcmat, "Render/Render.Mixed.Glass.IOR", "");
605
    QString renderNormal = value(fcmat, "Render/Render.Mixed.Normal", "");
606
    QString renderTransparencyValue = value(fcmat, "Render/Render.Mixed.Transparency", "");
607

608
    // Split out the textures
609
    QString renderDiffuseColor;
610
    QString renderDiffuseColorTexture;
611
    QString renderDiffuseColorObject;
612
    splitTextureObject(renderDiffuseColorValue,
613
                       &renderDiffuseColorTexture,
614
                       &renderDiffuseColor,
615
                       &renderDiffuseColorObject);
616
    QString renderGlassColor;
617
    QString renderGlassColorTexture;
618
    QString renderGlassColorObject;
619
    splitTextureObject(renderGlassColorValue,
620
                       &renderGlassColorTexture,
621
                       &renderGlassColor,
622
                       &renderGlassColorObject);
623
    QString renderGlassIOR;
624
    QString renderGlassIORTexture;
625
    splitTexture(renderGlassIORValue, &renderGlassIORTexture, &renderGlassIOR);
626
    QString renderTransparency;
627
    QString renderTransparencyTexture;
628
    splitTexture(renderTransparencyValue, &renderTransparencyTexture, &renderTransparency);
629

630
    if (!renderBump.isEmpty() || !renderDiffuseColorValue.isEmpty() || !renderDisplacement.isEmpty()
631
        || !renderGlassColorValue.isEmpty() || !renderGlassIORValue.isEmpty()
632
        || !renderNormal.isEmpty() || !renderTransparencyValue.isEmpty()) {
633
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Mixed);
634

635
        // Now add the data
636
        setAppearanceValue(finalModel, "Render.Mixed.Bump", renderBump);
637
        setAppearanceValue(finalModel, "Render.Mixed.Diffuse.Color", renderDiffuseColor);
638
        setAppearanceValue(finalModel,
639
                           "Render.Mixed.Diffuse.Color.Texture",
640
                           renderDiffuseColorTexture);
641
        setAppearanceValue(finalModel,
642
                           "Render.Mixed.Diffuse.Color.Object",
643
                           renderDiffuseColorObject);
644
        setAppearanceValue(finalModel, "Render.Mixed.Displacement", renderDisplacement);
645
        setAppearanceValue(finalModel, "Render.Mixed.Glass.Color", renderGlassColor);
646
        setAppearanceValue(finalModel, "Render.Mixed.Glass.Color.Texture", renderGlassColorTexture);
647
        setAppearanceValue(finalModel, "Render.Mixed.Glass.Color.Object", renderGlassColorObject);
648
        setAppearanceValue(finalModel, "Render.Mixed.Glass.IOR", renderGlassIOR);
649
        setAppearanceValue(finalModel, "Render.Mixed.Glass.IOR.Texture", renderGlassIORTexture);
650
        setAppearanceValue(finalModel, "Render.Mixed.Normal", renderNormal);
651
        setAppearanceValue(finalModel, "Render.Mixed.Transparency", renderTransparency);
652
        setAppearanceValue(finalModel,
653
                           "Render.Mixed.Transparency.Texture",
654
                           renderTransparencyTexture);
655
    }
656
}
657

658
void MaterialConfigLoader::addRenderOspray(QMap<QString, QString>& fcmat,
659
                                           const std::shared_ptr<Material>& finalModel)
660
{
661
    QString prefix = QString::fromStdString("Render.Ospray");
662
    QString string = multiLineKey(fcmat, prefix);
663

664
    if (!string.isEmpty()) {
665
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Ospray);
666

667
        // Now add the data
668
        setAppearanceValue(finalModel, "Render.Ospray", string);
669
    }
670
}
671

672
void MaterialConfigLoader::addRenderPbrt(QMap<QString, QString>& fcmat,
673
                                         const std::shared_ptr<Material>& finalModel)
674
{
675
    QString prefix = QString::fromStdString("Render.Pbrt");
676
    QString string = multiLineKey(fcmat, prefix);
677

678
    if (!string.isEmpty()) {
679
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Pbrt);
680

681
        // Now add the data
682
        setAppearanceValue(finalModel, "Render.Pbrt", string);
683
    }
684
}
685

686
void MaterialConfigLoader::addRenderPovray(QMap<QString, QString>& fcmat,
687
                                           const std::shared_ptr<Material>& finalModel)
688
{
689
    QString prefix = QString::fromStdString("Render.Povray");
690
    QString string = multiLineKey(fcmat, prefix);
691

692
    if (!string.isEmpty()) {
693
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Povray);
694

695
        // Now add the data
696
        setAppearanceValue(finalModel, "Render.Povray", string);
697
    }
698
}
699

700
void MaterialConfigLoader::addRenderSubstancePBR(QMap<QString, QString>& fcmat,
701
                                                 const std::shared_ptr<Material>& finalModel)
702
{
703
    QString renderBaseColorValue = value(fcmat, "Render/Render.Substance_PBR.BaseColor", "");
704
    QString renderBump = value(fcmat, "Render/Render.Substance_PBR.Bump", "");
705
    QString renderMetallicValue = value(fcmat, "Render/Render.Substance_PBR.Metallic", "");
706
    QString renderNormal = value(fcmat, "Render/Render.Substance_PBR.Normal", "");
707
    QString renderRoughnessValue = value(fcmat, "Render/Render.Substance_PBR.Roughness", "");
708
    QString renderSpecularValue = value(fcmat, "Render/Render.Substance_PBR.Specular", "");
709

710
    // Split out the textures
711
    QString renderBaseColor;
712
    QString renderBaseColorTexture;
713
    QString renderBaseColorObject;
714
    splitTextureObject(renderBaseColorValue,
715
                       &renderBaseColorTexture,
716
                       &renderBaseColor,
717
                       &renderBaseColorObject);
718
    QString renderMetallic;
719
    QString renderMetallicTexture;
720
    splitTexture(renderMetallicValue, &renderMetallicTexture, &renderMetallic);
721
    QString renderRoughness;
722
    QString renderRoughnessTexture;
723
    splitTexture(renderRoughnessValue, &renderRoughnessTexture, &renderRoughness);
724
    QString renderSpecular;
725
    QString renderSpecularTexture;
726
    splitTexture(renderSpecularValue, &renderSpecularTexture, &renderSpecular);
727

728
    if (!renderBaseColorValue.isEmpty() || !renderBump.isEmpty() || !renderMetallicValue.isEmpty()
729
        || !renderNormal.isEmpty() || !renderRoughnessValue.isEmpty()
730
        || !renderSpecularValue.isEmpty()) {
731
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_SubstancePBR);
732

733
        // Now add the data
734
        setAppearanceValue(finalModel, "Render.Substance_PBR.BaseColor", renderBaseColor);
735
        setAppearanceValue(finalModel,
736
                           "Render.Substance_PBR.BaseColor.Texture",
737
                           renderBaseColorTexture);
738
        setAppearanceValue(finalModel,
739
                           "Render.Substance_PBR.BaseColor.Object",
740
                           renderBaseColorObject);
741
        setAppearanceValue(finalModel, "Render.Substance_PBR.Bump", renderBump);
742
        setAppearanceValue(finalModel, "Render.Substance_PBR.Metallic", renderMetallic);
743
        setAppearanceValue(finalModel,
744
                           "Render.Substance_PBR.Metallic.Texture",
745
                           renderMetallicTexture);
746
        setAppearanceValue(finalModel, "Render.Substance_PBR.Normal", renderNormal);
747
        setAppearanceValue(finalModel, "Render.Substance_PBR.Roughness", renderRoughness);
748
        setAppearanceValue(finalModel,
749
                           "Render.Substance_PBR.Roughness.Texture",
750
                           renderRoughnessTexture);
751
        setAppearanceValue(finalModel, "Render.Substance_PBR.Specular", renderSpecular);
752
        setAppearanceValue(finalModel,
753
                           "Render.Substance_PBR.Specular.Texture",
754
                           renderSpecularTexture);
755
    }
756
}
757

758
void MaterialConfigLoader::addRenderTexture(QMap<QString, QString>& fcmat,
759
                                            const std::shared_ptr<Material>& finalModel)
760
{
761
    QString renderName;
762
    auto renderImage = std::make_shared<QList<QVariant>>();
763
    QString renderScale;
764
    QString renderRotation;
765
    QString renderTranslationU;
766
    QString renderTranslationV;
767

768
    auto keys = fcmat.keys();
769
    for (const auto& key : keys) {
770
        if (key.startsWith(QString::fromStdString("Render/Render.Textures."))) {
771
            QStringList list1 = key.split(QLatin1Char('.'));
772
            if (renderName.isEmpty()) {
773
                renderName = list1[2];
774
            }
775
            if (list1[3] == QString::fromStdString("Images")) {
776
                renderImage->push_back(value(fcmat, key.toStdString(), ""));
777
            }
778
            else if (list1[3] == QString::fromStdString("Scale")) {
779
                renderScale = value(fcmat, key.toStdString(), "");
780
            }
781
            else if (list1[3] == QString::fromStdString("Rotation")) {
782
                renderRotation = value(fcmat, key.toStdString(), "");
783
            }
784
            else if (list1[3] == QString::fromStdString("TranslationU")) {
785
                renderTranslationU = value(fcmat, key.toStdString(), "");
786
            }
787
            else if (list1[3] == QString::fromStdString(" TranslationV")) {
788
                renderTranslationV = value(fcmat, key.toStdString(), "");
789
            }
790
        }
791
    }
792

793
    if (!renderName.isEmpty()) {
794
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Render_Texture);
795

796
        // Now add the data
797
        setAppearanceValue(finalModel, "Render.Textures.Name", renderName);
798
        setAppearanceValue(finalModel, "Render.Textures.Images", renderImage);
799
        setAppearanceValue(finalModel, "Render.Textures.Scale", renderScale);
800
        setAppearanceValue(finalModel, "Render.Textures.Rotation", renderRotation);
801
        setAppearanceValue(finalModel, "Render.Textures.TranslationU", renderTranslationU);
802
        setAppearanceValue(finalModel, "Render.Textures.TranslationV", renderTranslationV);
803
    }
804
}
805

806
void MaterialConfigLoader::addRenderWB(QMap<QString, QString>& fcmat,
807
                                       const std::shared_ptr<Material>& finalModel)
808
{
809
    QString useObjectColor = value(fcmat, "General/UseObjectColor", "");
810
    QString renderType = value(fcmat, "Render/Render.Type", "");
811

812
    if (!renderType.isEmpty()) {
813
        finalModel->addAppearance(ModelUUIDs::ModelUUID_RenderWB);
814

815
        // Now add the data
816
        setAppearanceValue(finalModel, "UseObjectColor", useObjectColor);
817
        setAppearanceValue(finalModel, "Render.Type", renderType);
818
    }
819

820
    addRenderAppleseed(fcmat, finalModel);
821
    addRenderCarpaint(fcmat, finalModel);
822
    addRenderCycles(fcmat, finalModel);
823
    addRenderDiffuse(fcmat, finalModel);
824
    addRenderDisney(fcmat, finalModel);
825
    addRenderEmission(fcmat, finalModel);
826
    addRenderGlass(fcmat, finalModel);
827
    addRenderLuxcore(fcmat, finalModel);
828
    addRenderLuxrender(fcmat, finalModel);
829
    addRenderMixed(fcmat, finalModel);
830
    addRenderOspray(fcmat, finalModel);
831
    addRenderPbrt(fcmat, finalModel);
832
    addRenderPovray(fcmat, finalModel);
833
    addRenderSubstancePBR(fcmat, finalModel);
834
    addRenderTexture(fcmat, finalModel);
835
}
836

837
void MaterialConfigLoader::addCosts(const QMap<QString, QString>& fcmat,
838
                                    const std::shared_ptr<Material>& finalModel)
839
{
840
    QString productURL = value(fcmat, "Cost/ProductURL", "");
841
    QString specificPrice = value(fcmat, "Cost/SpecificPrice", "");
842
    QString vendor = value(fcmat, "Cost/Vendor", "");
843

844
    if (productURL.length() + specificPrice.length() + vendor.length() > 0) {
845
        finalModel->addPhysical(ModelUUIDs::ModelUUID_Costs_Default);
846

847
        // Now add the data
848
        setPhysicalValue(finalModel, "ProductURL", productURL);
849
        setPhysicalValue(finalModel, "SpecificPrice", specificPrice);
850
        setPhysicalValue(finalModel, "Vendor", vendor);
851
    }
852
}
853

854
void MaterialConfigLoader::addArchitectural(const QMap<QString, QString>& fcmat,
855
                                            const std::shared_ptr<Material>& finalModel)
856
{
857
    QString color = value(fcmat, "Architectural/Color", "");
858
    QString environmentalEfficiencyClass =
859
        value(fcmat, "Architectural/EnvironmentalEfficiencyClass", "");
860
    QString executionInstructions = value(fcmat, "Architectural/ExecutionInstructions", "");
861
    QString finish = value(fcmat, "Architectural/Finish", "");
862
    QString fireResistanceClass = value(fcmat, "Architectural/FireResistanceClass", "");
863
    QString model = value(fcmat, "Architectural/Model", "");
864
    QString soundTransmissionClass = value(fcmat, "Architectural/SoundTransmissionClass", "");
865
    QString unitsPerQuantity = value(fcmat, "Architectural/UnitsPerQuantity", "");
866

867
    if (environmentalEfficiencyClass.length() + executionInstructions.length()
868
            + fireResistanceClass.length() + model.length() + soundTransmissionClass.length()
869
            + unitsPerQuantity.length()
870
        > 0) {
871
        finalModel->addPhysical(ModelUUIDs::ModelUUID_Architectural_Default);
872
    }
873
    if (color.length() + finish.length() > 0) {
874
        finalModel->addAppearance(ModelUUIDs::ModelUUID_Rendering_Architectural);
875
    }
876

877
    // Now add the data
878
    setPhysicalValue(finalModel, "EnvironmentalEfficiencyClass", environmentalEfficiencyClass);
879
    setPhysicalValue(finalModel, "ExecutionInstructions", executionInstructions);
880
    setPhysicalValue(finalModel, "FireResistanceClass", fireResistanceClass);
881
    setPhysicalValue(finalModel, "Model", model);
882
    setPhysicalValue(finalModel, "SoundTransmissionClass", soundTransmissionClass);
883
    setPhysicalValue(finalModel, "UnitsPerQuantity", unitsPerQuantity);
884

885
    setAppearanceValue(finalModel, "Color", color);
886
    setAppearanceValue(finalModel, "Finish", finish);
887
}
888

889
void MaterialConfigLoader::addElectromagnetic(const QMap<QString, QString>& fcmat,
890
                                              const std::shared_ptr<Material>& finalModel)
891
{
892
    QString relativePermittivity = value(fcmat, "Electromagnetic/RelativePermittivity", "");
893
    QString electricalConductivity = value(fcmat, "Electromagnetic/ElectricalConductivity", "");
894
    QString relativePermeability = value(fcmat, "Electromagnetic/RelativePermeability", "");
895

896
    if (relativePermittivity.length() + electricalConductivity.length()
897
            + relativePermeability.length()
898
        > 0) {
899
        finalModel->addPhysical(ModelUUIDs::ModelUUID_Electromagnetic_Default);
900

901
        // Now add the data
902
        setPhysicalValue(finalModel, "RelativePermittivity", relativePermittivity);
903
        setPhysicalValue(finalModel, "ElectricalConductivity", electricalConductivity);
904
        setPhysicalValue(finalModel, "RelativePermeability", relativePermeability);
905
    }
906
}
907

908
void MaterialConfigLoader::addThermal(const QMap<QString, QString>& fcmat,
909
                                      const std::shared_ptr<Material>& finalModel)
910
{
911
    QString specificHeat = value(fcmat, "Thermal/SpecificHeat", "");
912
    QString thermalConductivity = value(fcmat, "Thermal/ThermalConductivity", "");
913
    QString thermalExpansionCoefficient = value(fcmat, "Thermal/ThermalExpansionCoefficient", "");
914

915
    if (specificHeat.length() + thermalConductivity.length() + thermalExpansionCoefficient.length()
916
        > 0) {
917
        finalModel->addPhysical(ModelUUIDs::ModelUUID_Thermal_Default);
918

919
        // Now add the data
920
        setPhysicalValue(finalModel, "SpecificHeat", specificHeat);
921
        setPhysicalValue(finalModel, "ThermalConductivity", thermalConductivity);
922
        setPhysicalValue(finalModel, "ThermalExpansionCoefficient", thermalExpansionCoefficient);
923
    }
924
}
925

926
void MaterialConfigLoader::addFluid(const QMap<QString, QString>& fcmat,
927
                                    const std::shared_ptr<Material>& finalModel)
928
{
929
    QString density = value(fcmat, "Fluidic/Density", "");
930
    QString dynamicViscosity = value(fcmat, "Fluidic/DynamicViscosity", "");
931
    QString kinematicViscosity = value(fcmat, "Fluidic/KinematicViscosity", "");
932
    QString prandtlNumber = value(fcmat, "Fluidic/PrandtlNumber", "");
933

934
    // Check which model we need
935
    bool useDensity = false;
936
    bool useFluid = false;
937
    if (density.length() > 0) {
938
        useDensity = true;
939
    }
940
    if (dynamicViscosity.length() + kinematicViscosity.length() + prandtlNumber.length() > 0) {
941
        useFluid = true;
942
    }
943

944
    if (useFluid) {
945
        finalModel->addPhysical(ModelUUIDs::ModelUUID_Fluid_Default);
946
    }
947
    else if (useDensity) {
948
        finalModel->addPhysical(ModelUUIDs::ModelUUID_Mechanical_Density);
949
    }
950

951
    // Now add the data
952
    setPhysicalValue(finalModel, "Density", density);
953
    setPhysicalValue(finalModel, "DynamicViscosity", dynamicViscosity);
954
    setPhysicalValue(finalModel, "KinematicViscosity", kinematicViscosity);
955
    setPhysicalValue(finalModel, "PrandtlNumber", prandtlNumber);
956
}
957

958
void MaterialConfigLoader::addMechanical(const QMap<QString, QString>& fcmat,
959
                                         const std::shared_ptr<Material>& finalModel)
960
{
961
    QString density = value(fcmat, "Mechanical/Density", "");
962
    QString bulkModulus = value(fcmat, "Mechanical/BulkModulus", "");
963
    QString poissonRatio = value(fcmat, "Mechanical/PoissonRatio", "");
964
    QString shearModulus = value(fcmat, "Mechanical/ShearModulus", "");
965
    QString youngsModulus = value(fcmat, "Mechanical/YoungsModulus", "");
966
    QString angleOfFriction = value(fcmat, "Mechanical/AngleOfFriction", "");
967
    QString compressiveStrength = value(fcmat, "Mechanical/CompressiveStrength", "");
968
    QString fractureToughness = value(fcmat, "Mechanical/FractureToughness", "");
969
    QString ultimateStrain = value(fcmat, "Mechanical/UltimateStrain", "");
970
    QString ultimateTensileStrength = value(fcmat, "Mechanical/UltimateTensileStrength", "");
971
    QString yieldStrength = value(fcmat, "Mechanical/YieldStrength", "");
972
    QString stiffness = value(fcmat, "Mechanical/Stiffness", "");
973

974
    // Check which model we need
975
    bool useDensity = false;
976
    bool useIso = false;
977
    bool useLinearElastic = false;
978
    if (density.length() > 0) {
979
        useDensity = true;
980
    }
981
    if (bulkModulus.length() + poissonRatio.length() + shearModulus.length()
982
            + youngsModulus.length()
983
        > 0) {
984
        useIso = true;
985
    }
986
    if (angleOfFriction.length() + compressiveStrength.length() + fractureToughness.length()
987
            + ultimateStrain.length() + ultimateTensileStrength.length() + yieldStrength.length()
988
            + stiffness.length()
989
        > 0) {
990
        useLinearElastic = true;
991
    }
992

993
    if (useLinearElastic) {
994
        finalModel->addPhysical(ModelUUIDs::ModelUUID_Mechanical_LinearElastic);
995
    }
996
    else {
997
        if (useIso) {
998
            finalModel->addPhysical(ModelUUIDs::ModelUUID_Mechanical_IsotropicLinearElastic);
999
        }
1000
        if (useDensity) {
1001
            finalModel->addPhysical(ModelUUIDs::ModelUUID_Mechanical_Density);
1002
        }
1003
    }
1004

1005
    // Now add the data
1006
    setPhysicalValue(finalModel, "Density", density);
1007
    setPhysicalValue(finalModel, "BulkModulus", bulkModulus);
1008
    setPhysicalValue(finalModel, "PoissonRatio", poissonRatio);
1009
    setPhysicalValue(finalModel, "ShearModulus", shearModulus);
1010
    setPhysicalValue(finalModel, "YoungsModulus", youngsModulus);
1011
    setPhysicalValue(finalModel, "AngleOfFriction", angleOfFriction);
1012
    setPhysicalValue(finalModel, "CompressiveStrength", compressiveStrength);
1013
    setPhysicalValue(finalModel, "FractureToughness", fractureToughness);
1014
    setPhysicalValue(finalModel, "UltimateStrain", ultimateStrain);
1015
    setPhysicalValue(finalModel, "UltimateTensileStrength", ultimateTensileStrength);
1016
    setPhysicalValue(finalModel, "YieldStrength", yieldStrength);
1017
    setPhysicalValue(finalModel, "Stiffness", stiffness);
1018
}
1019

1020
void MaterialConfigLoader::addLegacy(const QMap<QString, QString>& fcmat,
1021
                                     const std::shared_ptr<Material>& finalModel)
1022
{
1023
    for (auto const& legacy : fcmat.keys()) {
1024
        auto name = legacy;
1025
        int last = name.lastIndexOf(QLatin1String("/"));
1026
        if (last > 0) {
1027
            name = name.mid(last + 1);
1028
        }
1029

1030
        if (!finalModel->hasNonLegacyProperty(name)) {
1031
            setLegacyValue(finalModel, name.toStdString(), fcmat[legacy]);
1032
        }
1033
    }
1034
}
1035

1036
std::shared_ptr<Material>
1037
MaterialConfigLoader::getMaterialFromPath(const std::shared_ptr<MaterialLibrary>& library,
1038
                                          const QString& path)
1039
{
1040
    QString author = getAuthorAndLicense(path);  // Place them both in the author field
1041

1042
    QMap<QString, QString> fcmat;
1043
    if (!readFile(path, fcmat)) {
1044
        Base::Console().Log("Error reading '%s'\n", path.toStdString().c_str());
1045
        throw MaterialReadError();
1046
    }
1047

1048
    // General section
1049
    // QString name = value(fcmat, "Name", ""); - always get the name from the filename
1050
    QFileInfo filepath(path);
1051
    QString name =
1052
        filepath.fileName().remove(QString::fromStdString(".FCMat"), Qt::CaseInsensitive);
1053
    QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces);
1054

1055
    QString description = value(fcmat, "Description", "");
1056
    QString sourceReference = value(fcmat, "ReferenceSource", "");
1057
    QString sourceURL = value(fcmat, "SourceURL", "");
1058

1059
    std::shared_ptr<Material> finalModel = std::make_shared<Material>(library, path, uuid, name);
1060
    finalModel->setOldFormat(true);
1061

1062
    finalModel->setAuthor(author);
1063
    finalModel->setDescription(description);
1064
    finalModel->setReference(sourceReference);
1065
    finalModel->setURL(sourceURL);
1066

1067
    QString father = value(fcmat, "Father", "");
1068
    if (!father.isEmpty()) {
1069
        finalModel->addPhysical(ModelUUIDs::ModelUUID_Legacy_Father);
1070

1071
        // Now add the data
1072
        setPhysicalValue(finalModel, "Father", father);
1073
    }
1074

1075
    QString kindOfMaterial = value(fcmat, "KindOfMaterial", "");
1076
    QString materialNumber = value(fcmat, "MaterialNumber", "");
1077
    QString norm = value(fcmat, "Norm", "");
1078
    QString standardCode = value(fcmat, "StandardCode", "");
1079
    if (kindOfMaterial.length() + materialNumber.length() + norm.length() + standardCode.length()
1080
        > 0) {
1081
        finalModel->addPhysical(ModelUUIDs::ModelUUID_Legacy_MaterialStandard);
1082

1083
        // Now add the data
1084
        setPhysicalValue(finalModel, "KindOfMaterial", kindOfMaterial);
1085
        setPhysicalValue(finalModel, "MaterialNumber", materialNumber);
1086
        setPhysicalValue(finalModel, "StandardCode", norm);  // Norm is the same as StandardCode
1087
        setPhysicalValue(finalModel, "StandardCode", standardCode);
1088
    }
1089

1090
    // Add the remaining sections
1091
    addMechanical(fcmat, finalModel);
1092
    addFluid(fcmat, finalModel);
1093
    addThermal(fcmat, finalModel);
1094
    addElectromagnetic(fcmat, finalModel);
1095
    addArchitectural(fcmat, finalModel);
1096
    addCosts(fcmat, finalModel);
1097
    addRendering(fcmat, finalModel);
1098
    addVectorRendering(fcmat, finalModel);
1099
    addRenderWB(fcmat, finalModel);
1100
    addLegacy(fcmat, finalModel);
1101

1102
    return finalModel;
1103
}
1104

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.