~ubuntu-branches/ubuntu/utopic/slic3r/utopic

« back to all changes in this revision

Viewing changes to xs/src/Model.cpp

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2014-06-17 01:27:26 UTC
  • Revision ID: package-import@ubuntu.com-20140617012726-2wrs4zdo251nr4vg
Tags: upstream-1.1.4+dfsg
ImportĀ upstreamĀ versionĀ 1.1.4+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "Model.hpp"
 
2
 
 
3
namespace Slic3r {
 
4
 
 
5
Model::Model() {}
 
6
 
 
7
Model::Model(const Model &other)
 
8
{
 
9
    // copy materials
 
10
    for (ModelMaterialMap::const_iterator i = other.materials.begin(); i != other.materials.end(); ++i)
 
11
        this->add_material(i->first, *i->second);
 
12
    
 
13
    // copy objects
 
14
    this->objects.reserve(other.objects.size());
 
15
    for (ModelObjectPtrs::const_iterator i = other.objects.begin(); i != other.objects.end(); ++i)
 
16
        this->add_object(**i);
 
17
}
 
18
 
 
19
Model& Model::operator= (Model other)
 
20
{
 
21
    this->swap(other);
 
22
    return *this;
 
23
}
 
24
 
 
25
void
 
26
Model::swap(Model &other)
 
27
{
 
28
    std::swap(this->materials,  other.materials);
 
29
    std::swap(this->objects,    other.objects);
 
30
}
 
31
 
 
32
Model::~Model()
 
33
{
 
34
    this->clear_objects();
 
35
    this->clear_materials();
 
36
}
 
37
 
 
38
ModelObject*
 
39
Model::add_object()
 
40
{
 
41
    ModelObject* new_object = new ModelObject(this);
 
42
    this->objects.push_back(new_object);
 
43
    return new_object;
 
44
}
 
45
 
 
46
ModelObject*
 
47
Model::add_object(const ModelObject &other)
 
48
{
 
49
    ModelObject* new_object = new ModelObject(this, other);
 
50
    this->objects.push_back(new_object);
 
51
    return new_object;
 
52
}
 
53
 
 
54
void
 
55
Model::delete_object(size_t idx)
 
56
{
 
57
    ModelObjectPtrs::iterator i = this->objects.begin() + idx;
 
58
    delete *i;
 
59
    this->objects.erase(i);
 
60
}
 
61
 
 
62
void
 
63
Model::clear_objects()
 
64
{
 
65
    // int instead of size_t because it can be -1 when vector is empty
 
66
    for (int i = this->objects.size()-1; i >= 0; --i)
 
67
        this->delete_object(i);
 
68
}
 
69
 
 
70
void
 
71
Model::delete_material(t_model_material_id material_id)
 
72
{
 
73
    ModelMaterialMap::iterator i = this->materials.find(material_id);
 
74
    if (i != this->materials.end()) {
 
75
        delete i->second;
 
76
        this->materials.erase(i);
 
77
    }
 
78
}
 
79
 
 
80
void
 
81
Model::clear_materials()
 
82
{
 
83
    while (!this->materials.empty())
 
84
        this->delete_material( this->materials.begin()->first );
 
85
}
 
86
 
 
87
ModelMaterial*
 
88
Model::add_material(t_model_material_id material_id)
 
89
{
 
90
    ModelMaterial* material = this->get_material(material_id);
 
91
    if (material == NULL) {
 
92
        material = this->materials[material_id] = new ModelMaterial(this);
 
93
    }
 
94
    return material;
 
95
}
 
96
 
 
97
ModelMaterial*
 
98
Model::add_material(t_model_material_id material_id, const ModelMaterial &other)
 
99
{
 
100
    // delete existing material if any
 
101
    ModelMaterial* material = this->get_material(material_id);
 
102
    if (material != NULL) {
 
103
        delete material;
 
104
    }
 
105
    
 
106
    // set new material
 
107
    material = new ModelMaterial(this, other);
 
108
    this->materials[material_id] = material;
 
109
    return material;
 
110
}
 
111
 
 
112
ModelMaterial*
 
113
Model::get_material(t_model_material_id material_id)
 
114
{
 
115
    ModelMaterialMap::iterator i = this->materials.find(material_id);
 
116
    if (i == this->materials.end()) {
 
117
        return NULL;
 
118
    } else {
 
119
        return i->second;
 
120
    }
 
121
}
 
122
 
 
123
/*
 
124
void
 
125
Model::duplicate_objects_grid(unsigned int x, unsigned int y, coordf_t distance)
 
126
{
 
127
    if (this->objects.size() > 1) throw "Grid duplication is not supported with multiple objects";
 
128
    if (this->objects.empty()) throw "No objects!";
 
129
 
 
130
    ModelObject* object = this->objects.front();
 
131
    object->clear_instances();
 
132
 
 
133
    BoundingBoxf3 bb;
 
134
    object->bounding_box(&bb);
 
135
    Sizef3 size = bb.size();
 
136
 
 
137
    for (unsigned int x_copy = 1; x_copy <= x; ++x_copy) {
 
138
        for (unsigned int y_copy = 1; y_copy <= y; ++y_copy) {
 
139
            ModelInstance* instance = object->add_instance();
 
140
            instance->offset.x = (size.x + distance) * (x_copy-1);
 
141
            instance->offset.y = (size.y + distance) * (y_copy-1);
 
142
        }
 
143
    }
 
144
}
 
145
*/
 
146
 
 
147
bool
 
148
Model::has_objects_with_no_instances() const
 
149
{
 
150
    for (ModelObjectPtrs::const_iterator i = this->objects.begin();
 
151
        i != this->objects.end(); ++i)
 
152
    {
 
153
        if ((*i)->instances.empty()) {
 
154
            return true;
 
155
        }
 
156
    }
 
157
 
 
158
    return false;
 
159
}
 
160
 
 
161
#ifdef SLIC3RXS
 
162
REGISTER_CLASS(Model, "Model");
 
163
#endif
 
164
 
 
165
 
 
166
ModelMaterial::ModelMaterial(Model *model) : model(model) {}
 
167
ModelMaterial::ModelMaterial(Model *model, const ModelMaterial &other)
 
168
    : model(model), config(other.config), attributes(other.attributes)
 
169
{}
 
170
 
 
171
void
 
172
ModelMaterial::apply(const t_model_material_attributes &attributes)
 
173
{
 
174
    this->attributes.insert(attributes.begin(), attributes.end());
 
175
}
 
176
 
 
177
 
 
178
#ifdef SLIC3RXS
 
179
REGISTER_CLASS(ModelMaterial, "Model::Material");
 
180
#endif
 
181
 
 
182
 
 
183
ModelObject::ModelObject(Model *model)
 
184
    : model(model)
 
185
{}
 
186
 
 
187
ModelObject::ModelObject(Model *model, const ModelObject &other)
 
188
:   model(model),
 
189
    input_file(other.input_file),
 
190
    instances(),
 
191
    volumes(),
 
192
    config(other.config),
 
193
    layer_height_ranges(other.layer_height_ranges),
 
194
    origin_translation(other.origin_translation),
 
195
    _bounding_box(other._bounding_box),
 
196
    _bounding_box_valid(other._bounding_box_valid)
 
197
{
 
198
 
 
199
    this->volumes.reserve(other.volumes.size());
 
200
    for (ModelVolumePtrs::const_iterator i = other.volumes.begin(); i != other.volumes.end(); ++i)
 
201
        this->add_volume(**i);
 
202
 
 
203
    this->instances.reserve(other.instances.size());
 
204
    for (ModelInstancePtrs::const_iterator i = other.instances.begin(); i != other.instances.end(); ++i)
 
205
        this->add_instance(**i);
 
206
}
 
207
 
 
208
ModelObject& ModelObject::operator= (ModelObject other)
 
209
{
 
210
    this->swap(other);
 
211
    return *this;
 
212
}
 
213
 
 
214
void
 
215
ModelObject::swap(ModelObject &other)
 
216
{
 
217
    std::swap(this->input_file,             other.input_file);
 
218
    std::swap(this->instances,              other.instances);
 
219
    std::swap(this->volumes,                other.volumes);
 
220
    std::swap(this->config,                 other.config);
 
221
    std::swap(this->layer_height_ranges,    other.layer_height_ranges);
 
222
    std::swap(this->origin_translation,     other.origin_translation);
 
223
    std::swap(this->_bounding_box,          other._bounding_box);
 
224
    std::swap(this->_bounding_box_valid,    other._bounding_box_valid);
 
225
}
 
226
 
 
227
ModelObject::~ModelObject()
 
228
{
 
229
    this->clear_volumes();
 
230
    this->clear_instances();
 
231
}
 
232
 
 
233
ModelVolume*
 
234
ModelObject::add_volume(const TriangleMesh &mesh)
 
235
{
 
236
    ModelVolume* v = new ModelVolume(this, mesh);
 
237
    this->volumes.push_back(v);
 
238
    this->invalidate_bounding_box();
 
239
    return v;
 
240
}
 
241
 
 
242
ModelVolume*
 
243
ModelObject::add_volume(const ModelVolume &other)
 
244
{
 
245
    ModelVolume* v = new ModelVolume(this, other);
 
246
    this->volumes.push_back(v);
 
247
    this->invalidate_bounding_box();
 
248
    return v;
 
249
}
 
250
 
 
251
void
 
252
ModelObject::delete_volume(size_t idx)
 
253
{
 
254
    ModelVolumePtrs::iterator i = this->volumes.begin() + idx;
 
255
    delete *i;
 
256
    this->volumes.erase(i);
 
257
    this->invalidate_bounding_box();
 
258
}
 
259
 
 
260
void
 
261
ModelObject::clear_volumes()
 
262
{
 
263
    // int instead of size_t because it can be -1 when vector is empty
 
264
    for (int i = this->volumes.size()-1; i >= 0; --i)
 
265
        this->delete_volume(i);
 
266
}
 
267
 
 
268
ModelInstance*
 
269
ModelObject::add_instance()
 
270
{
 
271
    ModelInstance* i = new ModelInstance(this);
 
272
    this->instances.push_back(i);
 
273
    this->invalidate_bounding_box();
 
274
    return i;
 
275
}
 
276
 
 
277
ModelInstance*
 
278
ModelObject::add_instance(const ModelInstance &other)
 
279
{
 
280
    ModelInstance* i = new ModelInstance(this, other);
 
281
    this->instances.push_back(i);
 
282
    this->invalidate_bounding_box();
 
283
    return i;
 
284
}
 
285
 
 
286
void
 
287
ModelObject::delete_instance(size_t idx)
 
288
{
 
289
    ModelInstancePtrs::iterator i = this->instances.begin() + idx;
 
290
    delete *i;
 
291
    this->instances.erase(i);
 
292
    this->invalidate_bounding_box();
 
293
}
 
294
 
 
295
void
 
296
ModelObject::delete_last_instance()
 
297
{
 
298
    this->delete_instance(this->instances.size() - 1);
 
299
}
 
300
 
 
301
void
 
302
ModelObject::clear_instances()
 
303
{
 
304
    for (size_t i = 0; i < this->instances.size(); ++i)
 
305
        this->delete_instance(i);
 
306
}
 
307
 
 
308
void
 
309
ModelObject::invalidate_bounding_box()
 
310
{
 
311
    this->_bounding_box_valid = false;
 
312
}
 
313
 
 
314
#ifdef SLIC3RXS
 
315
REGISTER_CLASS(ModelObject, "Model::Object");
 
316
#endif
 
317
 
 
318
 
 
319
ModelVolume::ModelVolume(ModelObject* object, const TriangleMesh &mesh)
 
320
:   object(object), mesh(mesh), modifier(false)
 
321
{}
 
322
 
 
323
ModelVolume::ModelVolume(ModelObject* object, const ModelVolume &other)
 
324
:   object(object), mesh(other.mesh), modifier(other.modifier)
 
325
{
 
326
    this->material_id(other.material_id());
 
327
}
 
328
 
 
329
t_model_material_id
 
330
ModelVolume::material_id() const
 
331
{
 
332
    return this->_material_id;
 
333
}
 
334
 
 
335
void
 
336
ModelVolume::material_id(t_model_material_id material_id)
 
337
{
 
338
    this->_material_id = material_id;
 
339
    
 
340
    // ensure this->_material_id references an existing material
 
341
    (void)this->object->get_model()->add_material(material_id);
 
342
}
 
343
 
 
344
ModelMaterial*
 
345
ModelVolume::material() const
 
346
{
 
347
    return this->object->get_model()->get_material(this->_material_id);
 
348
}
 
349
 
 
350
#ifdef SLIC3RXS
 
351
REGISTER_CLASS(ModelVolume, "Model::Volume");
 
352
#endif
 
353
 
 
354
 
 
355
ModelInstance::ModelInstance(ModelObject *object)
 
356
:   object(object), rotation(0), scaling_factor(1)
 
357
{}
 
358
 
 
359
ModelInstance::ModelInstance(ModelObject *object, const ModelInstance &other)
 
360
:   object(object), rotation(other.rotation), scaling_factor(other.scaling_factor), offset(other.offset)
 
361
{}
 
362
 
 
363
#ifdef SLIC3RXS
 
364
REGISTER_CLASS(ModelInstance, "Model::Instance");
 
365
#endif
 
366
 
 
367
}