@@ -62,6 +62,7 @@ const std::string SHARED_BOUNDARY = "shared_boundary";
6262const std::string SHARED_BOUNDARY_FIRST_DOMAIN = " shared_boundary_first_domain" ;
6363const std::string SHARED_BOUNDARY_SECOND_DOMAIN = " shared_boundary_second_domain" ;
6464const std::string SHARED_BOUNDARY_TOLERANCE = " shared_boundary_tolerance" ;
65+ const std::string SHARED_BOUNDARIES = " shared_boundaries" ;
6566
6667} // namespace Keys
6768
@@ -107,59 +108,90 @@ const bool shared_boundary = false;
107108const std::string shared_boundary_first_domain = " " ;
108109const std::string shared_boundary_second_domain = " " ;
109110const double shared_boundary_tolerance = 1e-1 ;
111+ const std::string shared_boundaries = " " ; // Empty string = no boundaries
110112
111113} // namespace Defaults
112114
115+ // Helper methods for SharedBoundary struct
116+ // ---------------------------------------------------------------------------
117+ std::string GroomParameters::SharedBoundary::to_string () const {
118+ return first_domain + " |" + second_domain + " |" + std::to_string (tolerance);
119+ }
120+
121+ // ---------------------------------------------------------------------------
122+ GroomParameters::SharedBoundary GroomParameters::SharedBoundary::from_string (const std::string& str) {
123+ std::vector<std::string> parts;
124+ std::stringstream ss (str);
125+ std::string item;
126+
127+ while (std::getline (ss, item, ' |' )) {
128+ parts.push_back (item);
129+ }
130+
131+ if (parts.size () != 3 ) {
132+ throw std::runtime_error (" Invalid shared boundary string format" );
133+ }
134+
135+ SharedBoundary boundary;
136+ boundary.first_domain = parts[0 ];
137+ boundary.second_domain = parts[1 ];
138+ boundary.tolerance = std::stod (parts[2 ]);
139+ return boundary;
140+ }
141+
113142// ---------------------------------------------------------------------------
114143GroomParameters::GroomParameters (ProjectHandle project, std::string domain_name)
115144 : project_(project), domain_name_(domain_name) {
116145 params_ = project_->get_parameters (Parameters::GROOM_PARAMS, domain_name_);
117146
118- std::vector<std::string> all_params = {Keys::CROP,
119- Keys::REFLECT,
120- Keys::REFLECT_COLUMN,
121- Keys::REFLECT_CHOICE,
122- Keys::REFLECT_AXIS,
123- Keys::RESAMPLE,
124- Keys::ISOTROPIC,
125- Keys::ISO_SPACING,
126- Keys::SPACING,
127- Keys::CONVERT_MESH,
128- Keys::FILL_MESH_HOLES,
129- Keys::FILL_HOLES,
130- Keys::ISOLATE,
131- Keys::PAD,
132- Keys::PAD_VALUE,
133- Keys::ANTIALIAS,
134- Keys::ANTIALIAS_AMOUNT,
135- Keys::BLUR,
136- Keys::BLUR_SIGMA,
137- Keys::FASTMARCHING,
138- Keys::MESH_SMOOTH,
139- Keys::MESH_SMOOTHING_METHOD,
140- Keys::MESH_SMOOTHING_VTK_LAPLACIAN_ITERATIONS,
141- Keys::MESH_SMOOTHING_VTK_LAPLACIAN_RELAXATION,
142- Keys::MESH_SMOOTHING_VTK_WINDOWED_SINC_ITERATIONS,
143- Keys::MESH_SMOOTHING_VTK_WINDOWED_SINC_PASSBAND,
144- Keys::ALIGNMENT_METHOD,
145- Keys::ALIGNMENT_ENABLED,
146- Keys::ALIGNMENT_REFERENCE,
147- Keys::ALIGNMENT_REFERENCE_CHOSEN,
148- Keys::ALIGNMENT_SUBSET_SIZE,
149- Keys::GROOM_OUTPUT_PREFIX,
150- Keys::REMESH,
151- Keys::REMESH_PERCENT_MODE,
152- Keys::REMESH_PERCENT,
153- Keys::REMESH_NUM_VERTICES,
154- Keys::REMESH_GRADATION,
155- Keys::GROOM_ALL_DOMAINS_THE_SAME,
156- Keys::SKIP_GROOMING,
157- Keys::CENTER,
158- Keys::ICP,
159- Keys::SHARED_BOUNDARY,
160- Keys::SHARED_BOUNDARY_FIRST_DOMAIN,
161- Keys::SHARED_BOUNDARY_SECOND_DOMAIN,
162- Keys::SHARED_BOUNDARY_TOLERANCE};
147+ std::vector<std::string> all_params = {
148+ Keys::CROP,
149+ Keys::REFLECT,
150+ Keys::REFLECT_COLUMN,
151+ Keys::REFLECT_CHOICE,
152+ Keys::REFLECT_AXIS,
153+ Keys::RESAMPLE,
154+ Keys::ISOTROPIC,
155+ Keys::ISO_SPACING,
156+ Keys::SPACING,
157+ Keys::CONVERT_MESH,
158+ Keys::FILL_MESH_HOLES,
159+ Keys::FILL_HOLES,
160+ Keys::ISOLATE,
161+ Keys::PAD,
162+ Keys::PAD_VALUE,
163+ Keys::ANTIALIAS,
164+ Keys::ANTIALIAS_AMOUNT,
165+ Keys::BLUR,
166+ Keys::BLUR_SIGMA,
167+ Keys::FASTMARCHING,
168+ Keys::MESH_SMOOTH,
169+ Keys::MESH_SMOOTHING_METHOD,
170+ Keys::MESH_SMOOTHING_VTK_LAPLACIAN_ITERATIONS,
171+ Keys::MESH_SMOOTHING_VTK_LAPLACIAN_RELAXATION,
172+ Keys::MESH_SMOOTHING_VTK_WINDOWED_SINC_ITERATIONS,
173+ Keys::MESH_SMOOTHING_VTK_WINDOWED_SINC_PASSBAND,
174+ Keys::ALIGNMENT_METHOD,
175+ Keys::ALIGNMENT_ENABLED,
176+ Keys::ALIGNMENT_REFERENCE,
177+ Keys::ALIGNMENT_REFERENCE_CHOSEN,
178+ Keys::ALIGNMENT_SUBSET_SIZE,
179+ Keys::GROOM_OUTPUT_PREFIX,
180+ Keys::REMESH,
181+ Keys::REMESH_PERCENT_MODE,
182+ Keys::REMESH_PERCENT,
183+ Keys::REMESH_NUM_VERTICES,
184+ Keys::REMESH_GRADATION,
185+ Keys::GROOM_ALL_DOMAINS_THE_SAME,
186+ Keys::SKIP_GROOMING,
187+ Keys::CENTER,
188+ Keys::ICP,
189+ Keys::SHARED_BOUNDARY,
190+ Keys::SHARED_BOUNDARY_FIRST_DOMAIN,
191+ Keys::SHARED_BOUNDARY_SECOND_DOMAIN,
192+ Keys::SHARED_BOUNDARY_TOLERANCE,
193+ Keys::SHARED_BOUNDARIES,
194+ };
163195
164196 std::vector<std::string> to_remove;
165197
@@ -497,40 +529,93 @@ bool GroomParameters::get_skip_grooming() { return params_.get(Keys::SKIP_GROOMI
497529void GroomParameters::set_skip_grooming (bool skip) { params_.set (Keys::SKIP_GROOMING, skip); }
498530
499531// ---------------------------------------------------------------------------
500- bool GroomParameters::get_shared_boundary () { return params_.get (Keys::SHARED_BOUNDARY, Defaults::shared_boundary); }
532+ bool GroomParameters::get_shared_boundaries_enabled () {
533+ return params_.get (Keys::SHARED_BOUNDARY, Defaults::shared_boundary);
534+ }
501535
502536// ---------------------------------------------------------------------------
503- void GroomParameters::set_shared_boundary (bool shared_boundary ) { params_.set (Keys::SHARED_BOUNDARY, shared_boundary ); }
537+ void GroomParameters::set_shared_boundaries_enabled (bool enabled ) { params_.set (Keys::SHARED_BOUNDARY, enabled ); }
504538
505539// ---------------------------------------------------------------------------
506- std::string GroomParameters::get_shared_boundary_first_domain () {
507- return params_.get (Keys::SHARED_BOUNDARY_FIRST_DOMAIN, Defaults::shared_boundary_first_domain);
508- }
540+ std::vector<GroomParameters::SharedBoundary> GroomParameters::get_shared_boundaries () {
541+ std::vector<SharedBoundary> boundaries;
509542
510- // ---------------------------------------------------------------------------
511- void GroomParameters::set_shared_boundary_first_domain (const std::string& domain_name) {
512- params_.set (Keys::SHARED_BOUNDARY_FIRST_DOMAIN, domain_name);
543+ // Try new format first
544+ if (params_.key_exists (Keys::SHARED_BOUNDARIES)) {
545+ std::string boundaries_str = params_.get (Keys::SHARED_BOUNDARIES, Defaults::shared_boundaries);
546+ if (!boundaries_str.empty ()) {
547+ std::stringstream ss (boundaries_str);
548+ std::string boundary_str;
549+
550+ while (std::getline (ss, boundary_str, ' ;' )) {
551+ if (!boundary_str.empty ()) {
552+ try {
553+ boundaries.push_back (SharedBoundary::from_string (boundary_str));
554+ } catch (const std::exception& e) {
555+ SW_WARN (" Failed to parse shared boundary: " + boundary_str);
556+ }
557+ }
558+ }
559+ }
560+ return boundaries;
561+ }
562+
563+ // Migration: convert old single boundary format
564+ if (params_.get (Keys::SHARED_BOUNDARY, Defaults::shared_boundary)) {
565+ SharedBoundary boundary;
566+ boundary.first_domain =
567+ std::string (params_.get (Keys::SHARED_BOUNDARY_FIRST_DOMAIN, Defaults::shared_boundary_first_domain));
568+ boundary.second_domain =
569+ std::string (params_.get (Keys::SHARED_BOUNDARY_SECOND_DOMAIN, Defaults::shared_boundary_second_domain));
570+ boundary.tolerance = params_.get (Keys::SHARED_BOUNDARY_TOLERANCE, Defaults::shared_boundary_tolerance);
571+ boundaries.push_back (boundary);
572+
573+ // Migrate to new format
574+ set_shared_boundaries (boundaries);
575+ }
576+
577+ return boundaries;
513578}
514579
515580// ---------------------------------------------------------------------------
516- std::string GroomParameters::get_shared_boundary_second_domain () {
517- return params_.get (Keys::SHARED_BOUNDARY_SECOND_DOMAIN, Defaults::shared_boundary_second_domain);
581+ void GroomParameters::set_shared_boundaries (const std::vector<SharedBoundary>& boundaries) {
582+ if (boundaries.empty ()) {
583+ params_.set (Keys::SHARED_BOUNDARIES, " " );
584+ } else {
585+ std::string boundaries_str;
586+ for (size_t i = 0 ; i < boundaries.size (); ++i) {
587+ if (i > 0 ) boundaries_str += " ;" ;
588+ boundaries_str += boundaries[i].to_string ();
589+ }
590+ params_.set (Keys::SHARED_BOUNDARIES, boundaries_str);
591+ }
592+
593+ // Clear old format keys to avoid confusion
594+ params_.remove_entry (Keys::SHARED_BOUNDARY);
595+ params_.remove_entry (Keys::SHARED_BOUNDARY_FIRST_DOMAIN);
596+ params_.remove_entry (Keys::SHARED_BOUNDARY_SECOND_DOMAIN);
597+ params_.remove_entry (Keys::SHARED_BOUNDARY_TOLERANCE);
518598}
519599
520600// ---------------------------------------------------------------------------
521- void GroomParameters::set_shared_boundary_second_domain (const std::string& domain_name) {
522- params_.set (Keys::SHARED_BOUNDARY_SECOND_DOMAIN, domain_name);
601+ void GroomParameters::add_shared_boundary (const std::string& first_domain, const std::string& second_domain,
602+ double tolerance) {
603+ auto boundaries = get_shared_boundaries ();
604+ boundaries.push_back ({first_domain, second_domain, tolerance});
605+ set_shared_boundaries (boundaries);
523606}
524607
525608// ---------------------------------------------------------------------------
526- double GroomParameters::get_shared_boundary_tolerance () {
527- return params_.get (Keys::SHARED_BOUNDARY_TOLERANCE, Defaults::shared_boundary_tolerance);
609+ void GroomParameters::remove_shared_boundary (size_t index) {
610+ auto boundaries = get_shared_boundaries ();
611+ if (index < boundaries.size ()) {
612+ boundaries.erase (boundaries.begin () + index);
613+ set_shared_boundaries (boundaries);
614+ }
528615}
529616
530617// ---------------------------------------------------------------------------
531- void GroomParameters::set_shared_boundary_tolerance (double tolerance) {
532- params_.set (Keys::SHARED_BOUNDARY_TOLERANCE, tolerance);
533- }
618+ void GroomParameters::clear_shared_boundaries () { set_shared_boundaries ({}); }
534619
535620// ---------------------------------------------------------------------------
536621} // namespace shapeworks
0 commit comments