29 #define _unused(x) ((void)(x)) 31 #include "SUAPI-CppWrapper/model/Model.hpp" 35 #include "SUAPI-CppWrapper/model/Layer.hpp" 36 #include "SUAPI-CppWrapper/model/Axes.hpp" 37 #include "SUAPI-CppWrapper/model/Entities.hpp" 40 #include "SUAPI-CppWrapper/model/ComponentDefinition.hpp" 41 #include "SUAPI-CppWrapper/model/InstancePath.hpp" 42 #include "SUAPI-CppWrapper/model/Material.hpp" 43 #include "SUAPI-CppWrapper/model/AttributeDictionary.hpp" 44 #include "SUAPI-CppWrapper/model/TypedValue.hpp" 45 #include "SUAPI-CppWrapper/model/OptionsManager.hpp" 46 #include "SUAPI-CppWrapper/model/RenderingOptions.hpp" 47 #include "SUAPI-CppWrapper/model/ShadowInfo.hpp" 53 SUModelRef Model::create_model() {
54 SUModelRef model = SU_INVALID;
55 SUResult res = SUModelCreate(&model);
56 assert(res == SU_ERROR_NONE); _unused(res);
62 m_model(create_model()),
63 m_release_on_destroy(true)
67 Model::Model(SUModelRef model_ref,
bool release_on_destroy):
69 m_release_on_destroy(release_on_destroy)
72 Model::Model(std::string file_path):
74 m_release_on_destroy(true),
75 m_result(SUModelCreateFromFile(&m_model, file_path.c_str()))
78 Model::Model(
const Model& other):
79 m_model(other.m_model),
80 m_release_on_destroy(other.m_release_on_destroy)
84 if (m_release_on_destroy && SUIsValid(m_model)) {
85 SUResult res = SUModelRelease(&m_model);
86 assert(res == SU_ERROR_NONE); _unused(res);
96 Model::operator SUModelRef()
const {
101 Model::operator SUModelRef*() {
106 Model::operator bool()
const {
107 if (m_result == SU_ERROR_NONE) {
120 int major = 0, minor = 0, build = 0;
121 SUResult res = SUModelGetVersion(m_model, &major, &minor, &build);
122 assert(res == SU_ERROR_NONE); _unused(res);
123 std::string version = std::to_string(major) +
"." + std::to_string(minor) +
"." + std::to_string(build);
128 Layer Model::active_layer()
const {
130 throw std::logic_error(
"CW::Model::active_layer(): Model is null");
132 SULayerRef layer = SU_INVALID;
133 SUResult res = SUModelGetDefaultLayer(m_model, &layer);
134 assert(res == SU_ERROR_NONE); _unused(res);
149 throw std::logic_error(
"CW::Model::add_definition(): Model is null");
151 std::vector<ComponentDefinition> defs = {definition};
152 return add_definitions(defs);
156 bool Model::add_definitions(std::vector<ComponentDefinition>& definitions) {
158 throw std::logic_error(
"CW::Model::add_definitions(): Model is null");
160 std::vector<SUComponentDefinitionRef> defs(definitions.size(), SU_INVALID);
161 std::transform(definitions.begin(), definitions.end(), defs.begin(),
163 return definition.ref();
166 SUResult res = SUModelAddComponentDefinitions(m_model, definitions.size(), defs.data());
167 if (res == SU_ERROR_NONE) {
174 std::vector<AttributeDictionary> Model::attribute_dictionaries()
const {
176 throw std::logic_error(
"CW::Model::attribute_dictionaries(): Model is null");
179 SUResult res = SUModelGetNumAttributeDictionaries(m_model, &count);
180 assert(res == SU_ERROR_NONE);
181 std::vector<SUAttributeDictionaryRef> dict_refs(count, SU_INVALID);
182 res = SUModelGetAttributeDictionaries(m_model, count, dict_refs.data(), &count);
183 assert(res == SU_ERROR_NONE); _unused(res);
184 std::vector<AttributeDictionary> dicts(count);
185 std::transform(dict_refs.begin(), dict_refs.end(), dicts.begin(),
186 [](
const SUAttributeDictionaryRef& value){
195 throw std::logic_error(
"CW::Model::attribute_dictionary(): Model is null");
197 SUAttributeDictionaryRef dict = SU_INVALID;
198 SUResult res = SUModelGetAttributeDictionary(m_model, dict_name.c_str(), &dict);
199 assert(res == SU_ERROR_NONE); _unused(res);
205 Axes Model::axes()
const {
207 throw std::logic_error(
"CW::Model::axes(): Model is null");
209 SUAxesRef axes = SU_INVALID;
210 SUResult res = SUModelGetAxes(m_model, &axes);
211 assert(res == SU_ERROR_NONE); _unused(res);
238 std::vector<ComponentDefinition> Model::definitions()
const {
240 throw std::logic_error(
"CW::Model::definitions(): Model is null");
243 SUResult res = SUModelGetNumComponentDefinitions(m_model, &count);
244 assert(res == SU_ERROR_NONE);
245 std::vector<SUComponentDefinitionRef> def_refs(count, SU_INVALID);
246 res = SUModelGetComponentDefinitions(m_model, count, def_refs.data(), &count);
247 assert(res == SU_ERROR_NONE); _unused(res);
248 std::vector<ComponentDefinition> defs(count);
249 std::transform(def_refs.begin(), def_refs.end(), defs.begin(),
250 [](
const SUComponentDefinitionRef& value){
257 std::vector<ComponentDefinition> Model::group_definitions()
const {
259 throw std::logic_error(
"CW::Model::group_definitions(): Model is null");
262 SUResult res = SUModelGetNumGroupDefinitions(m_model, &count);
263 assert(res == SU_ERROR_NONE);
264 std::vector<SUComponentDefinitionRef> def_refs(count, SU_INVALID);
265 res = SUModelGetGroupDefinitions(m_model, count, def_refs.data(), &count);
266 assert(res == SU_ERROR_NONE); _unused(res);
267 std::vector<ComponentDefinition> defs(count);
268 std::transform(def_refs.begin(), def_refs.end(), defs.begin(),
269 [](
const SUComponentDefinitionRef& value){
277 SUInstancePathRef instance_path_ref = SU_INVALID;
278 SUResult res = SUInstancePathCreate(&instance_path_ref);
279 assert(res == SU_ERROR_NONE);
280 res = SUModelGetInstancePathByPid(m_model, persistent_id.ref(), &instance_path_ref);
281 if (res == SU_ERROR_GENERIC) {
285 assert(res == SU_ERROR_NONE); _unused(res);
292 throw std::logic_error(
"CW::Model::entities(): Model is null");
294 SUEntitiesRef entities = SU_INVALID;
295 SUResult res = SUModelGetEntities(m_model, &entities);
296 assert(res == SU_ERROR_NONE); _unused(res);
320 throw std::logic_error(
"CW::Model::get_attribute(): Model is null");
325 TypedValue Model::get_attribute(
const std::string& dict_name,
const std::string& key,
const TypedValue& default_value)
const {
327 throw std::logic_error(
"CW::Model::get_attribute(): Model is null");
330 return get_attribute(dictionary, key, default_value);
343 std::vector<Layer> Model::layers()
const {
345 throw std::logic_error(
"CW::Model::layers(): Model is null");
348 SUResult res = SUModelGetNumLayers(m_model, &count);
349 assert(res == SU_ERROR_NONE);
350 std::vector<SULayerRef> layer_refs(count, SU_INVALID);
351 res = SUModelGetLayers(m_model, count, layer_refs.data(), &count);
352 assert(res == SU_ERROR_NONE); _unused(res);
353 std::vector<Layer> layers(count);
354 std::transform(layer_refs.begin(), layer_refs.end(), layers.begin(),
355 [](
const SULayerRef& value){
363 for (
size_t i=0; i < layers.size(); i++) {
365 if (layers[i].attached()) {
366 throw std::invalid_argument(
"CW::Model::add_layers(): At least one of the Layer objects passed is attached to another model. Use Layer::copy() to create a new unattached Layer object and try again.");
369 std::vector<SULayerRef> layer_refs(layers.size(), SU_INVALID);
370 std::transform(layers.begin(), layers.end(), layer_refs.begin(),
371 [](
const Layer& value){
374 SUResult res = SUModelAddLayers(m_model, layers.size(), layer_refs.data());
375 assert(res == SU_ERROR_NONE); _unused(res);
376 for (
size_t i=0; i < layers.size(); i++) {
377 layers[i].attached(
true);
383 std::vector<Layer> layers = this->layers();
384 for (
auto& lay : layers) {
399 std::vector<Material> Model::materials()
const {
401 throw std::logic_error(
"CW::Model::materials(): Model is null");
404 SUResult res = SUModelGetNumMaterials(m_model, &count);
405 assert(res == SU_ERROR_NONE);
407 return std::vector<Material> {};
409 std::vector<SUMaterialRef> material_refs(count, SU_INVALID);
410 res = SUModelGetMaterials(m_model, count, material_refs.data(), &count);
411 assert(res == SU_ERROR_NONE); _unused(res);
412 std::vector<Material> materials(count);
413 std::transform(material_refs.begin(), material_refs.end(), materials.begin(),
414 [](
const SUMaterialRef& value){
422 for (
size_t i=0; i < materials.size(); i++) {
424 if (materials[i].attached()) {
425 throw std::invalid_argument(
"CW::Model::add_materials(): At least one of the Material objects passed is attached to another model. Use Material::copy() to create a new unattached Material object and try again.");
428 std::vector<SUMaterialRef> material_refs(materials.size(), SU_INVALID);
429 std::transform(materials.begin(), materials.end(), material_refs.begin(),
433 SUResult res = SUModelAddMaterials(m_model, materials.size(), material_refs.data());
434 assert(res == SU_ERROR_NONE); _unused(res);
435 for (
size_t i=0; i < materials.size(); i++) {
436 materials[i].attached(
true);
442 std::vector<Material> materials = this->materials();
443 for (
auto& mat : materials) {
444 if (mat == material) {
452 String Model::name()
const {
454 throw std::logic_error(
"CW::Model::name(): Model is null");
456 SUStringRef name = SU_INVALID;
457 SUModelGetName(m_model, &name);
462 bool Model::name(
const String& name_string) {
464 throw std::logic_error(
"CW::Model::name(): Model is null");
466 std::string std_string = name_string;
467 SUResult res = SUModelSetName(m_model, std_string.c_str());
468 if (res == SU_ERROR_NONE) {
475 size_t Model::num_faces()
const {
477 throw std::logic_error(
"CW::Model::num_faces(): Model is null");
480 return model_statistics.
faces();
485 SUOptionsManagerRef options_manager = SU_INVALID;
486 SUResult res = SUModelGetOptionsManager(m_model, &options_manager);
487 assert(res == SU_ERROR_NONE); _unused(res);
509 SUResult Model::save(
const std::string& file_path) {
511 throw std::logic_error(
"CW::Model::save(): Model is null");
513 const char * c_string = file_path.c_str();
514 SUResult res = SUModelSaveToFile(m_model, c_string);
519 bool Model::save_with_version(
const std::string& file_path, SUModelVersion version) {
521 throw std::logic_error(
"CW::Model::save_with_version(): Model is null");
523 SUResult res = SUModelSaveToFileWithVersion(m_model, file_path.c_str(), version);
524 if (res == SU_ERROR_NONE) {
540 throw std::logic_error(
"CW::Model::set_attribute(): Model is null");
545 bool Model::set_attribute(
const std::string& dict_name,
const std::string& key,
const TypedValue& value) {
547 throw std::logic_error(
"CW::Model::set_attribute(): Model is null");
550 return set_attribute(dict, key, value);
555 SURenderingOptionsRef
ref = SU_INVALID;
556 SUResult res = SUModelGetRenderingOptions(m_model, &ref);
557 assert(res == SU_ERROR_NONE); _unused(res);
563 SUShadowInfoRef
ref = SU_INVALID;
564 SUResult res = SUModelGetShadowInfo(m_model, &ref);
565 assert(res == SU_ERROR_NONE); _unused(res);
592 ModelStatistics::ModelStatistics(SUModelStatistics model_statistics):
593 m_model_statistics(model_statistics)
596 ModelStatistics::ModelStatistics(
const Model& model):
597 m_model_statistics(SUModelStatistics{})
599 SUResult res = SUModelGetStatistics(model, &m_model_statistics);
600 assert(res == SU_ERROR_NONE); _unused(res);
603 int ModelStatistics::edges()
const 605 return m_model_statistics.entity_counts[SUModelStatistics::SUEntityType_Edge];
610 return m_model_statistics.entity_counts[SUModelStatistics::SUEntityType_Face];
612 int ModelStatistics::instances()
const 614 return m_model_statistics.entity_counts[SUModelStatistics::SUEntityType_ComponentInstance];
616 int ModelStatistics::groups()
const 618 return m_model_statistics.entity_counts[SUModelStatistics::SUEntityType_Group];
620 int ModelStatistics::definitions()
const 622 return m_model_statistics.entity_counts[SUModelStatistics::SUEntityType_ComponentDefinition];
624 int ModelStatistics::layers()
const 626 return m_model_statistics.entity_counts[SUModelStatistics::SUEntityType_Layer];
628 int ModelStatistics::materials()
const 630 return m_model_statistics.entity_counts[SUModelStatistics::SUEntityType_Material];
632 int ModelStatistics::images()
const 634 return m_model_statistics.entity_counts[SUModelStatistics::SUEntityType_Image];
void add_layers(std::vector< Layer > &layers)
std::string version_string() const
bool layer_exists(const Layer &layer) const
void add_materials(std::vector< Material > &materials)
InstancePath instance_path(const String &persistent_id) const
TypedValue get_attribute(const std::string &key, const TypedValue &default_value) const
RenderingOptions rendering_options()
RenderingOptions.
bool material_exists(const Material &material) const
bool add_definition(ComponentDefinition &definition)
bool set_attribute(const std::string &key, const TypedValue &value)