@@ -223,17 +223,19 @@ CsgOpNode::CsgOpNode() {}
223
223
224
224
CsgOpNode::CsgOpNode (const std::vector<std::shared_ptr<CsgNode>> &children,
225
225
OpType op)
226
- : impl_(std::make_shared<Impl>()) {
227
- impl_->children_ = children;
226
+ : impl_(Impl{}) {
227
+ auto impl = impl_.GetGuard ();
228
+ impl->children_ = children;
228
229
SetOp (op);
229
230
// opportunistically flatten the tree without costly evaluation
230
231
GetChildren (false );
231
232
}
232
233
233
234
CsgOpNode::CsgOpNode (std::vector<std::shared_ptr<CsgNode>> &&children,
234
235
OpType op)
235
- : impl_(std::make_shared<Impl>()) {
236
- impl_->children_ = children;
236
+ : impl_(Impl{}) {
237
+ auto impl = impl_.GetGuard ();
238
+ impl->children_ = children;
237
239
SetOp (op);
238
240
// opportunistically flatten the tree without costly evaluation
239
241
GetChildren (false );
@@ -243,27 +245,30 @@ std::shared_ptr<CsgNode> CsgOpNode::Transform(const glm::mat4x3 &m) const {
243
245
auto node = std::make_shared<CsgOpNode>();
244
246
node->impl_ = impl_;
245
247
node->transform_ = m * glm::mat4 (transform_);
248
+ node->op_ = op_;
246
249
return node;
247
250
}
248
251
249
252
std::shared_ptr<CsgLeafNode> CsgOpNode::ToLeafNode () const {
250
253
if (cache_ != nullptr ) return cache_;
251
- if (impl_->children_ .empty ()) return nullptr ;
252
254
// turn the children into leaf nodes
253
255
GetChildren ();
254
- auto &children_ = impl_->children_ ;
256
+ auto impl = impl_.GetGuard ();
257
+ auto &children_ = impl->children_ ;
255
258
if (children_.size () > 1 ) {
256
- switch (impl_-> op_ ) {
259
+ switch (op_) {
257
260
case CsgNodeType::Union:
258
261
BatchUnion ();
259
262
break ;
260
263
case CsgNodeType::Intersection: {
261
264
std::vector<std::shared_ptr<const Manifold::Impl>> impls;
262
265
for (auto &child : children_) {
263
- impls.push_back (std::dynamic_pointer_cast<CsgLeafNode>(child)->GetImpl ());
266
+ impls.push_back (
267
+ std::dynamic_pointer_cast<CsgLeafNode>(child)->GetImpl ());
264
268
}
265
269
children_.clear ();
266
- children_.push_back (std::make_shared<CsgLeafNode>(BatchBoolean (OpType::Intersect, impls)));
270
+ children_.push_back (std::make_shared<CsgLeafNode>(
271
+ BatchBoolean (OpType::Intersect, impls)));
267
272
break ;
268
273
};
269
274
case CsgNodeType::Difference: {
@@ -283,6 +288,8 @@ std::shared_ptr<CsgLeafNode> CsgOpNode::ToLeafNode() const {
283
288
// unreachable
284
289
break ;
285
290
}
291
+ } else if (children_.size () == 0 ) {
292
+ return nullptr ;
286
293
}
287
294
// children_ must contain only one CsgLeafNode now, and its Transform will
288
295
// give CsgLeafNode as well
@@ -345,7 +352,8 @@ void CsgOpNode::BatchUnion() const {
345
352
// If the number of children exceeded this limit, we will operate on chunks
346
353
// with size kMaxUnionSize.
347
354
constexpr int kMaxUnionSize = 1000 ;
348
- auto &children_ = impl_->children_ ;
355
+ auto impl = impl_.GetGuard ();
356
+ auto &children_ = impl->children_ ;
349
357
while (children_.size () > 1 ) {
350
358
const int start = (children_.size () > kMaxUnionSize )
351
359
? (children_.size () - kMaxUnionSize )
@@ -392,7 +400,8 @@ void CsgOpNode::BatchUnion() const {
392
400
}
393
401
}
394
402
children_.erase (children_.begin () + start, children_.end ());
395
- children_.push_back (std::make_shared<CsgLeafNode>(BatchBoolean (OpType::Add, impls)));
403
+ children_.push_back (
404
+ std::make_shared<CsgLeafNode>(BatchBoolean (OpType::Add, impls)));
396
405
// move it to the front as we process from the back, and the newly added
397
406
// child should be quite complicated
398
407
std::swap (children_.front (), children_.back ());
@@ -408,18 +417,18 @@ void CsgOpNode::BatchUnion() const {
408
417
*/
409
418
std::vector<std::shared_ptr<CsgNode>> &CsgOpNode::GetChildren (
410
419
bool finalize) const {
411
- auto &children_ = impl_-> children_ ;
412
- if ( children_. empty () || (impl_-> simplified_ && !finalize) ||
413
- impl_ ->flattened_ )
420
+ auto impl = impl_. GetGuard () ;
421
+ auto & children_ = impl-> children_ ;
422
+ if (children_. empty () || (impl-> simplified_ && !finalize) || impl ->flattened_ )
414
423
return children_;
415
- impl_ ->simplified_ = true ;
416
- impl_ ->flattened_ = finalize;
424
+ impl ->simplified_ = true ;
425
+ impl ->flattened_ = finalize;
417
426
std::vector<std::shared_ptr<CsgNode>> newChildren;
418
427
419
- CsgNodeType op = impl_-> op_ ;
428
+ CsgNodeType op = op_;
420
429
for (auto &child : children_) {
421
430
if (child->GetNodeType () == op && child.use_count () == 1 &&
422
- std::dynamic_pointer_cast<CsgOpNode>(child)->impl_ .use_count () == 1 ) {
431
+ std::dynamic_pointer_cast<CsgOpNode>(child)->impl_ .UseCount () == 1 ) {
423
432
auto grandchildren =
424
433
std::dynamic_pointer_cast<CsgOpNode>(child)->GetChildren (finalize);
425
434
int start = children_.size ();
@@ -444,13 +453,13 @@ std::vector<std::shared_ptr<CsgNode>> &CsgOpNode::GetChildren(
444
453
void CsgOpNode::SetOp (OpType op) {
445
454
switch (op) {
446
455
case OpType::Add:
447
- impl_-> op_ = CsgNodeType::Union;
456
+ op_ = CsgNodeType::Union;
448
457
break ;
449
458
case OpType::Subtract:
450
- impl_-> op_ = CsgNodeType::Difference;
459
+ op_ = CsgNodeType::Difference;
451
460
break ;
452
461
case OpType::Intersect:
453
- impl_-> op_ = CsgNodeType::Intersection;
462
+ op_ = CsgNodeType::Intersection;
454
463
break ;
455
464
}
456
465
}
0 commit comments