1
2use serde::{Deserialize, Serialize};
3use wasm_bindgen::prelude::*;
4
5pub mod panic_hook;
10
11#[path = "geometry/tolerance.rs"]
12mod tolerance;
13pub use tolerance::{
14 curve_model_scale, model_scale, report_scale_migration, solid_model_scale, solid_scale,
15 offset_construction_band, vertex_tolerance_from_edges, KernelTolerances,
16 MeasuredTolerance, OFFSET_CONSTRUCTION_FLOOR, OFFSET_CONSTRUCTION_REL,
17 VERTEX_MATCH_FLOOR, VOLUME_DRIFT_ABS, VOLUME_DRIFT_REL,
18};
19#[path = "geometry/entity_tolerance.rs"]
24mod entity_tolerance;
25pub use entity_tolerance::{EntityTolerances, EDGE_CAP_FRACTION, VERTEX_CAP_FRACTION};
26#[path = "props/diagnostics.rs"]
27mod diagnostics;
28pub use diagnostics::{
29 Approximation, ApproximationBudget, Backing, BudgetMechanism, BudgetReason, MeasuredComponent, DiagnosticEvent, DiagnosticSeverity, EdgeOrigin, KernelDiagnostics,
30 KernelOutcome, KernelRefusal, OffCarrierEdge,
31 KernelStage, OrRefuse, RefusalClass, SoundnessDefect, UndecidedCause,
32};
33#[path = "geometry/polygon.rs"]
34mod polygon;
35#[path = "geometry/curve.rs"]
36mod curve;
37pub use curve::{
38 make_arc, make_circle, make_hyperbola, make_line, make_parabola, uniform_clamped_knots,
39 KnotVector, NurbsCurve, Vec4, KNOT_DEDUP_EPS, KNOT_IDENTITY_TOL,
40};
41#[path = "blending/blend/mod.rs"]
42mod blend;
43pub use blend::{
44 take_blend_approximations, take_blend_notes,
45 blend_timing_capture, take_blend_timings, BlendTiming,
46 blend_closed_edge, blend_edge_variable, blend_open_edge, blend_smooth_chain,
47 round_convex_corner,
48};
49#[path = "blending/fillet.rs"]
50mod fillet;
51pub use fillet::{
52 chamfer_edge, chamfer_edge_angle, chamfer_edge_asymmetric, chamfer_edges_angle,
53 chamfer_edges_asymmetric, fillet_edge, fillet_edges, fillet_edges_reported, fillet_edges_reported_at_offset,
54 fillet_edges_variable, fillet_edges_variable_law, fillet_edges_variable_vertex_radii,
55 BlendSelection,
56};
57#[path = "blending/law.rs"]
58mod law;
59pub use law::{LawSegment, RadiusLaw};
60#[path = "geometry/fit.rs"]
61mod fit;
62pub use fit::{
63 fit_polyline, fit_polyline_at, fit_polyline_of_degree, interpolate_curve, interpolate_curve_closed,
64 interpolate_curve_local, interpolate_curve_thinned, interpolate_curve_with_end_tangents,
65 simplify_polyline, simplify_polyline_indices, solve_banded, solve_dense, PolylineFit,
66 PolylineFitExit, PolylineFitLedger, PolylineFitReport, PolylineFitScope, MAX_FIT_STATIONS,
67};
68#[path = "geometry/image_curve.rs"]
69mod image_curve;
70pub use image_curve::{affine_image_curve, image_curve, image_curve_pair, ImageCurve, ImageCurveTier};
71#[path = "geometry/surface.rs"]
72mod surface;
73pub use surface::{
74 carrier_preview_patch, make_cone_surface, make_cylinder_surface, make_extrusion, make_plane,
75 make_revolution, make_sphere_surface, make_sphere_surface_framed, make_torus_surface,
76 ExtendRefusal, NurbsSurface, SurfaceSide, WeightSite, MAXIMUM_FOLD_ANGLE,
77 MAXIMUM_GROWTH_RATIO,
78};
79#[path = "geometry/control_cage.rs"]
80mod control_cage;
81pub use control_cage::{
82 CagePoint, CagePrimitive, ControlCage, CAGE_DEGREE, MAX_RINGS, MAX_SEGMENTS, MIN_RINGS,
83 MIN_SEGMENTS,
84};
85#[path = "geometry/coons.rs"]
86mod coons;
87pub use coons::{
88 coons_bilinear, coons_bilinear_reported, coons_with_ribbons, CompatWork, CoonsRefusal,
89 CoonsReport, RibbonReport,
90};
91#[path = "geometry/gordon.rs"]
92mod gordon;
93pub use gordon::{gordon_surface, gordon_surface_reported, GordonRefusal, GordonReport};
94#[path = "geometry/analytic_surface.rs"]
95mod analytic_surface;
96pub use analytic_surface::{
97 circle_angle_to_parameter, intersect_analytic_pair, plane_ruled_section_arc,
98 revolution_structure, AnalyticSurface, RevolutionFrame, RevolutionStructure,
99};
100pub(crate) use analytic_surface::{
101 canonical_carriers_enabled, canonicalise_carriers, intersect_analytic_pair_with, ruled_gate,
102 ruled_gate_census, CanonicalReport, CanonicalRewrite, RuledGate,
103};
104#[path = "geometry/sphere_chart.rs"]
105mod sphere_chart;
106pub use sphere_chart::{
107 canonicalize_points, chart_grid_divisions, chart_grid_parameters, corner_index,
108 cube_edge_corner, cube_edge_divisions, cube_edge_index, cube_edge_parameters,
109 cube_edge_parts, Chart, ChartSegment, ChartSide, SphereAtlas,
110 SphericalRegion, CHART_COUNT, CUBE_CORNER_COUNT, CUBE_EDGE_COUNT,
111};
112#[path = "brep/solid_codec.rs"]
113mod solid_codec;
114pub use solid_codec::{decode_solid, encode_solid, SolidNames, SOLID_CODEC_VERSION, SOLID_CODEC_VERSION_KIND};
115#[path = "brep/topology.rs"]
116mod topology;
117pub use topology::{
118 make_box_brep, make_cylinder_brep, make_pyramid_brep, topology_kind, BodyKind, BrepSolid, CellRecord,
119 FaceRecord, IssueKind, KindReport, TopologyKind, ValidationReport,
120};
121#[path = "brep/soundness.rs"]
122mod soundness;
123pub use soundness::{
124 face_self_intersections, loop_self_crossings, shell_vector_areas, solid_connectivity,
125 solid_euler, solid_self_intersections, ConnectivityReport, CrossingConfirmation, EulerReport,
126 CertificateScope, CertifiedFacePair, FaceCrossing, FaceFold, FaceVectorArea,
127 LoopCrossing, LoopCrossingReport, SelfIntersectionOptions, SelfIntersectionReport,
128 ClosureReading, ShellConnectivity, ShellVectorArea, VectorAreaReport, CrossingUndecidedCause, UndecidedCrossing,
129 MAX_LISTED_UNDECIDED,
130};
131#[path = "brep/topology_arena.rs"]
132mod topology_arena;
133pub use topology_arena::{
134 ArenaCoedge, ArenaEdge, ArenaFace, ArenaLoop, ArenaShell, ArenaVertex, CoedgeId, EdgeId,
135 FaceId, LoopId, ShellId, TopologyArena, VertexId,
136};
137#[path = "brep/analytic_topology.rs"]
138mod analytic_topology;
139pub use analytic_topology::{
140 make_cone_brep, make_sphere_brep, make_sphere_brep_framed, make_torus_brep,
141};
142#[path = "construction/sweep_topology.rs"]
143mod sweep_topology;
144pub(crate) use sweep_topology::is_sweep_tight_bend;
145pub use sweep_topology::{
146 extrude_profile_brep, extrude_profile_brep_draft, fit_helix_curve, helix_sample_points,
147 profile_anchor, rib_from_profile, sweep_bend_profile, sweep_closure, BendStation,
148 JointContinuity, PathJoint, SweepClosure,
149 RibExtrusion, RibNames, SweepPath, MAX_JOINT_TANGENT_BREAK, SWEEP_TIGHT_BEND_REFUSAL,
150 SWEEP_TWIST_CLOSURE_REFUSAL,
151 build_swept_envelope, recognize_swept_envelope, swept_envelope_volume, SweptEnvelope,
152 SWEEP_ENVELOPE_REFUSAL, sweep_envelope_bodies,
153 sweep_profile_along_chain, sweep_profile_along_chain_reported,
154 sweep_profile_along_chain_with_stations, sweep_profile_along_chain_with_stations_reported,
155 sweep_profile_along_path,
156 sweep_profile_along_path_anchored,
157 sweep_profile_helix,
158 sweep_profile_twisted, sweep_profile_twisted_anchored, ProfileAnchor, SectionPlacement,
159 StationBudget, SweepStationReport, SweptChain, SWEEP_DEFAULT_TOLERANCE, SWEEP_MAX_STATIONS,
160 SWEEP_REFINEMENT_ROUNDS,
161};
162#[path = "construction/revolve_topology.rs"]
163mod revolve_topology;
164pub use revolve_topology::{revolve_profile_brep, revolve_profile_brep_named};
165#[path = "construction/loft_topology.rs"]
166mod loft_topology;
167pub use loft_topology::{
168 loft_profile_brep, loft_profile_brep_closed, loft_profile_brep_guided,
169 loft_profile_brep_guided_frame, loft_profile_brep_tangent,
170};
171pub(crate) use loft_topology::loft_profile_brep_closed_shifted;
172#[path = "brep/transform_topology.rs"]
173mod transform_topology;
174#[path = "brep/recentre.rs"]
175mod recentre;
176pub use transform_topology::{mirror_brep, transform_brep, AffineTransform};
177#[path = "edit/split.rs"]
178mod split;
179pub use split::{
180 split_solid_by_face_surface, split_solid_by_plane, split_solid_by_surface, SplitSurface,
181};
182#[path = "props/mass_properties.rs"]
183mod mass_properties;
184pub use mass_properties::{
185 curve_arc_length, edge_arc_length, face_area, face_boundary_length, face_volume_contribution,
186 face_set_identity, mass_caller, parameter_space_area, solid_edge_length_total,
187 solid_mass_properties,
188 solid_mass_properties_full, signed_volume_against, solid_signed_volume, solid_signed_volume_for_sign, trim_polygons,
189 DensityMassProperties,
190 FaceSetIdentity, FullMassProperties, MassCaller, MassProperties, MassPropertiesCache,
191};
192#[path = "props/carrier_dimensions.rs"]
193mod carrier_dimensions;
194pub use carrier_dimensions::{curve_carrier_dimensions, surface_carrier_dimensions, CarrierDimensions};
195#[path = "meshing/tessellation.rs"]
196mod tessellation;
197pub use tessellation::{tessellate_brep, tessellate_face, TessellationOptions};
198#[path = "meshing/watertight_tessellation/mod.rs"]
199mod watertight_tessellation;
200pub use watertight_tessellation::{
201 sample_edge_polylines, sample_edges_encoded, tessellate_brep_watertight,
202 tessellate_brep_watertight_face_stride, tessellate_brep_watertight_face_stride_with_samples,
203};
204#[path = "feature_pipeline/mod.rs"]
209pub mod feature_pipeline;
210pub use feature_pipeline::execute_history_json;
211pub use feature_pipeline::{first_reference_name, reference_names};
212pub use feature_pipeline::face_transform_pivot;
216pub use feature_pipeline::{
219 clear_history_cache, execute_history, execute_history_observed, AddedSolid, Axis,
220 ComponentRecord, FeatureDescriptor, FeatureRefusal, FeatureResult, Frame, Fulfilment,
221 HistoryProgress, HistoryRequest, Rejected, RejectedKind,
222 HistoryResult, PortKind, PortRecord, ProfileLoop, ScenePoint, SketchProfile,
223};
224pub use feature_pipeline::wire_harness::{
228 bundle_diameter, Attachment as SplineAttachment, BundleStatus, PortSide, RouteResult,
229 RouteStatus,
230 WireHarnessBundle, WireHarnessConnection,
231 WireHarnessEndpoint, WireHarnessReport, WireHarnessState, BUNDLE_SOLID_PREFIX,
232 WIRE_HARNESS_FEATURE_ID, WIRE_HARNESS_FEATURE_TYPE,
233};
234pub use feature_pipeline::part_pins::{
239 declarations as declared_ports, declared_endpoints as declared_point_endpoints,
240 declared_points, endpoint_occurrence, follow_pin_edit, follow_point_edit, pin_labels,
241 pin_point_report, pins,
242 point_renames, port_group_for_unit, resolve_component_pin, resolve_part_pin,
243 unit_count as symbol_unit_count, unit_groups, DeclaredPin, DeclaredPoint, PinPoint,
244 PinPointChange, PinPointProblem, PinPointReport, PointRenames, DEFAULT_PORT_NAME,
245 DEFAULT_PORT_PURPOSE, PADS_BLOCK, SYMBOL_BLOCK,
246};
247pub use feature_pipeline::ports::{
252 address as port_address, document_is_boundary, seat_of as port_seat_of, seat_point,
253 seat_vector, seated_direction, split_address, unit_map, unseat_point, unseat_vector,
254 world_seat, PortDeclaration, PortPoint, PortPointRow, PortSeat, PortsReport, UnitProblem,
255 BOUNDARY_KEY, PORTS_BLOCK, PORTS_FEATURE_ID, PORTS_FEATURE_TYPE,
256};
257pub use feature_pipeline::pmi::{
261 balloon_head as pmi_balloon_head, clamp_text_size, format_dimension, format_number,
262 nearest_point_on_edge, nearest_point_on_solid, pmi_schema_catalogue, pmi_type,
263 nearest_displayed_point, nearest_displayed_point_on_edge, pose_apply as pmi_pose_apply, pose_unapply as pmi_pose_unapply,
264 resolve_state as pmi_resolve_state, BalloonAnchor, BalloonAnchorMode, FcfFrame, HalfSpace as PmiHalfSpace, HeadScope as PmiHeadScope, PmiAnnotation,
265 PmiAnnotationReport, PmiCamera, PmiDisplay, PmiGeometry, PmiPlane, PmiPose, PmiProjection, PmiReport,
266 PmiState, PmiStatus, PmiTypeDef, PmiView, PmiViewReport, SolidPoses as PmiSolidPoses, ToleranceBlock, ToleranceMode, PMI_TYPES,
267};
268pub use feature_pipeline::pmi::layout::{present as pmi_present, LayoutStyle as PmiLayoutStyle, Presentation as PmiPresentation};
269pub use feature_pipeline::pmi::annotations::fcf::{characteristic as pmi_characteristic, Characteristic as PmiCharacteristic, CHARACTERISTICS as PMI_CHARACTERISTICS};
270pub use feature_pipeline::assign_sketch_loop_ids;
274pub use feature_pipeline::features::sketch3d::{
278 reference_record as sketch3d_reference_record, resolve_reference as resolve_sketch3d_reference,
279 ResolvedReference as Sketch3dResolvedReference, REFERENCE_TIP_LENGTH as SKETCH3D_REFERENCE_TIP_LENGTH,
280 SKETCH3D_DOC_KEY, SKETCH3D_EDIT_BUTTON, SKETCH3D_FEATURE_TYPE, SKETCH3D_REFERENCES_PARAM,
281 SKETCH3D_REFS_KEY,
282};
283pub use feature_pipeline::{flat_pattern_dxf, flat_pattern_svg, is_sheet_metal_handle};
285pub use feature_pipeline::{pattern_component_instance, pattern_parse_suppressed};
287pub use feature_pipeline::{native_import_payload, native_import_payload_with_appearance};
291pub use feature_pipeline::IsolatedSceneMetadata;
294pub use feature_pipeline::scene_metadata_colors_json;
297pub use feature_pipeline::{
300 add_part_to_library, add_part_to_library_impl, install_parts_library, missing_library_parts,
301 parts_library_json, parts_library_map, parts_library_revision, refresh_library_entry,
302 refresh_library_entry_impl, same_build, follow_saved_rows, follow_saved_rows_known, kernel_source_stamp, stable_json_hash, PartsLibraryEntry, PartsLibraryMap,
303};
304pub use feature_pipeline::assembly::{
307 assembly_add_constraint_json, assembly_apply_document_json,
308 assembly_apply_inferred_constraints_json, assembly_component_entities_json, assembly_dof_json,
309 assembly_infer_constraints_json, assembly_inferable_types_json,
310 assembly_move_constraint_json, assembly_overlay_json, assembly_pose_updates_json,
311 assembly_drag_solve_json, assembly_frame_solve_json, assembly_remove_constraint_json, assembly_resolve_refs_json,
312 assembly_run_solve_json,
313 assembly_set_constraint_enabled_json, assembly_set_constraint_open_json,
314 assembly_state_json, assembly_statuses_json, assembly_update_constraint_json,
315 constraint_hidden_params, constraint_schema_catalogue,
316 assembly_add_constraint_impl, assembly_apply_document_impl, assembly_move_constraint_impl,
319 assembly_drag_solve_impl, assembly_frame_solve_impl, assembly_flip_plan_json, assembly_rebase_mechanical_impl, assembly_remove_constraint_impl, assembly_run_solve_impl,
320 assembly_set_constraint_enabled_impl, assembly_set_constraint_open_impl,
321 assembly_update_constraint_impl,
322 assembly_session_export, assembly_session_import, assembly_session_serial, RetiredSession, SessionTransfer,
323};
324pub use feature_pipeline::{AssemblyState, ConstraintEntry};
325pub use feature_pipeline::assembly::transform_to_pose_params;
328pub use feature_pipeline::feature_schema_catalogue;
331pub use feature_pipeline::feature_hidden_params;
334pub use feature_pipeline::assembly::{constraint_type, ConstraintTypeDef, CONSTRAINT_TYPES};
337pub use feature_pipeline::{feature_context_applicable, SelectionProbe};
338pub use feature_pipeline::Env;
344
345pub fn eval_expression(
350 expressions: &str,
351 configurator_json: &serde_json::Value,
352 source: &str,
353) -> Result<f64, String> {
354 Env::build(expressions, configurator_json).and_then(|env| env.eval(source))
355}
356
357#[cfg(feature = "wasm-threads")]
364pub use wasm_bindgen_rayon::init_thread_pool;
365#[path = "geometry/projection.rs"]
366mod projection;
367pub use projection::{
368 project_point_to_curve, project_point_to_surface, project_point_to_surface_seeded,
369 CurveProjection, SurfaceProjection,
370};
371#[doc(hidden)]
372pub use projection::{
373 project_point_to_surface_basin_census, project_point_to_surface_general_lanes, BasinCensus,
374 GlobalStats,
375};
376#[path = "intersect/curve_surface_intersection.rs"]
377mod curve_surface_intersection;
378pub use curve_surface_intersection::{intersect_curve_surface, CurveSurfaceIntersection};
379#[path = "intersect/exact_line_surface.rs"]
380mod exact_line_surface;
381#[path = "intersect/curve_curve_intersection.rs"]
382mod curve_curve_intersection;
383pub use curve_curve_intersection::{intersect_curves, CurveCurveIntersection};
384#[path = "intersect/surface_surface_intersection.rs"]
385mod surface_surface_intersection;
386pub use surface_surface_intersection::{
387 intersect_surfaces, intersect_surfaces_supplemental, SurfaceIntersectionCurve,
388 SurfaceIntersectionOptions,
389};
390pub(crate) use surface_surface_intersection::TRANSVERSE_SEED_CROSS;
391#[path = "intersect/tangent_curve.rs"]
392mod tangent_curve;
393pub use tangent_curve::{
394 classify_tangent_contact_at, find_tangent_contact, trace_tangent_curve, TangentContact,
395 EXTENDED_RANK_FLOOR,
396};
397#[path = "brep/classification.rs"]
398mod classification;
399pub use classification::{
400 classify_point, containment_lane, horizon_cross_frame, parameter_point_in_face,
401 trim_sample_count, trim_station, ContainmentLane, PointClass, PointClassification,
402 PolygonClass, SolidClassifier, COVERING_RIM_STRIP_SWITCH, HORIZON_CONTAINMENT_SWITCH,
403 HORIZON_CROSS_FRAME_SWITCH, HORIZON_SINGLE_LOOP_SWITCH, NO_SPHERE_CHART_TRIM_SWITCH,
404 SEAM_BAND_MERGED_SWITCH,
405};
406#[doc(hidden)]
407pub use classification::parameter_point_in_face_scan;
408#[path = "geometry/spatial.rs"]
409mod spatial;
410pub use spatial::{Aabb, Bvh};
411#[path = "brep/pair_classification.rs"]
412mod pair_classification;
413pub use pair_classification::{
414 classify_surface_pair, classify_surface_pair_cached, SurfaceClassifyData,
415 SurfacePairClassification, SurfacePairRelation,
416};
417#[path = "intersect/arrangement.rs"]
418mod arrangement;
419pub use arrangement::{
420 arrange_segments, point_in_polygon, segment_intersection, ArrangementPiece, ArrangementRegion,
421 CycleUse, Segment2, Vec2,
422};
423#[path = "geometry/pcurve.rs"]
424mod pcurve;
425pub use pcurve::{
426 build_pcurve_on_surface, build_pcurve_on_surface_marched, build_pcurve_on_surface_range,
427 build_pcurve_on_surface_range_dense, build_pcurve_on_surface_stations, fit_pcurve_on_surface,
428 fit_pcurve_on_surface_marched, fit_pcurve_on_surface_range, fit_pcurve_on_surface_range_dense,
429 fit_pcurve_on_surface_stations, PcurveFit, PcurveFitExit, PcurveFitLedger, PcurveFitReport,
430 PcurveFitScope, PCURVE_OFF_BAR, PCURVE_REFINEMENT_TOLERANCE,
431};
432#[path = "csg/imprint.rs"]
433mod imprint;
434pub use imprint::{
435 build_imprints, EdgeSplitRecord, FaceImprints, FaceKey, FacePcurve, ImprintOptions,
436 ImprintPieceRecord, ImprintResultRecord, ImprintVertex, TangentSectionRecord,
437};
438#[path = "csg/edge_split.rs"]
439mod edge_split;
440pub use edge_split::{apply_edge_splits, apply_edge_splits_with_map};
441#[path = "csg/fragment.rs"]
442mod fragment;
443pub use fragment::{
444 fragment_face, fragment_solid, FaceFragmentRecord, FragmentCoedge, FragmentEdgeSource,
445 FragmentLoop, FragmentOrder,
446};
447#[path = "csg/boolean/mod.rs"]
448mod boolean;
449pub use boolean::{
450 boolean_operation, boolean_operation_nary, boolean_operation_nary_with_options, boolean_operation_with_diagnostics, boolean_operation_with_diagnostics_at_offset, boolean_split_operands,
451 BooleanOperation, BooleanOptions,
452};
453#[path = "csg/oracle.rs"]
454mod oracle;
455pub use oracle::{
456 boolean_residual_fusables, boolean_semantic_disagreement, boolean_semantic_disagreement_nary,
457 OracleReport, ResidualFusable, ResidualKind, SemanticDisagreement, DISAGREEMENT_THRESHOLD,
458};
459#[path = "healing/heal.rs"]
460mod heal;
461#[path = "healing/reading_memo.rs"]
464mod reading_memo;
465#[path = "healing/accept.rs"]
471mod accept;
472pub use accept::{
473 accept_sound, accept_sound_against, accept_sound_against_scoped, resolve_face_crossing, resolve_face_crossing_between,
474 take_crossing_repairs,
475 CrossingRepairRecord,
476};
477#[path = "offset/point.rs"]
482mod offset_point;
483pub use offset_point::{OffsetEvaluator, OffsetNormal, OffsetSample};
484#[path = "offset/analytic_pair.rs"]
491mod offset_analytic_pair;
492#[path = "offset/retrim.rs"]
499mod offset_retrim;
500#[path = "offset/reintersect.rs"]
508mod offset_reintersect;
509#[path = "offset/measure.rs"]
519mod offset_measure;
520pub use offset_measure::{
521 measure_edge_against_pcurve_image, measure_surface_fit_against_pointwise_offset,
522 span_midpoint_error, vertex_endpoint_gap,
523};
524#[path = "offset/offset.rs"]
525mod offset;
526pub use offset::{
527 offset_face_carrier, offset_face_carrier_measured, offset_face_carrier_sided, offset_surface,
528 offset_surface_measured, offset_surface_measured_sided, CarrierDeviation, CarrierExtension,
529 MeasuredOffsetSurface, OffsetFaceCarrier, OffsetSurfaceLane,
530};
531#[path = "offset/regularity.rs"]
537mod offset_regularity;
538#[path = "offset/fold_locus.rs"]
544mod offset_fold_locus;
545#[path = "offset/carve.rs"]
551mod offset_carve;
552#[path = "offset/thicken.rs"]
553mod thicken;
554pub use thicken::{thicken_face_sheet, thicken_trimmed_sheet};
555#[path = "healing/coalesce.rs"]
556mod coalesce;
557pub use coalesce::{concatenate_exact_curve_pieces, merge_curve_continuation_edges};
558#[path = "healing/face_merge.rs"]
559mod face_merge;
560#[allow(dead_code)]
563#[path = "healing/faceted_repair.rs"]
564mod faceted_repair;
565pub use face_merge::{merge_faces_within, merge_same_surface_faces, merge_same_surface_faces_excluding, merge_same_surface_faces_scoped};
566pub use faceted_repair::{mesh_to_faceted_brep, repair_triangle_soup, MeshRepairReport};
567#[path = "offset/offset_shell.rs"]
568mod offset_shell;
569pub use offset_shell::{
570 offset_shell, offset_shell_by_boolean, offset_shell_with_diagnostics, offset_solid, OffsetCorners,
571 OffsetFaceRole, OffsetShellFaceImageRecord, OffsetShellResultRecord,
572};
573pub(crate) use offset_shell::{is_offset_shell_no_retained_face, is_offset_shell_open_curved_rim};
574#[path = "io/step_matrix.rs"]
575mod step_matrix;
576#[path = "io/step.rs"]
577mod step;
578pub use step::{
579 assembly_export_tree, audit_step_manifold, audit_step_pcurves, export_step,
580 export_step_assembly, export_step_assembly_report, export_step_report,
581 export_step_report_named, Mat4, StepAssemblyExport, StepColors, StepExportOccurrence,
582 StepExportProduct, StepExportReport, StepPmi, PART_ATTRIBUTES, PART_NUMBER,
583};
584#[path = "io/appearance.rs"]
588mod appearance;
589pub use appearance::{BodyAppearance, ImportedColor, COLOR_METADATA_KEY};
590#[path = "io/step_import/mod.rs"]
591mod step_import;
592pub use step_import::{
593 import_step, import_step_bodies, import_step_report, import_step_trim_readings, import_step_with_appearance,
594 occurrence_ref_parts, read_step_assembly, read_step_pmi, rewrite_occurrence_refs,
595 ImportedStep, StepAssembly, StepBodyError, StepBodyTrimReadings, StepEdgeReading, StepFaceReading, StepImportReport,
596 StepOccurrence, StepProduct, StepSuppliedTrim, StepTrimReadings, OCCURRENCE_REF_PREFIX,
597 STATED_PRECISION_INCONSISTENCY_RATIO,
598};
599#[doc(hidden)]
601pub fn io_step_text_for_tests(value: &str) -> String {
602 step::pmi::step_text(value)
603}
604#[doc(hidden)]
605pub fn io_step_decode_text_for_tests(value: &str) -> String {
606 step_import::decode_step_text_for_tests(value)
607}
608#[path = "io/iges/mod.rs"]
609mod iges;
610pub use iges::{export_iges, import_iges};
611#[path = "io/mesh_io.rs"]
612mod mesh_io;
613pub use mesh_io::{
614 read_binary_stl, read_obj, write_binary_stl, write_obj, ObjReadResult, StlReadResult,
615};
616#[path = "io/three_mf/mod.rs"]
622mod three_mf;
623pub use three_mf::{
624 read_3mf, write_3mf, ThreeMfError, ThreeMfInstance, ThreeMfMesh, ThreeMfReadResult,
625 ThreeMfSolid, ThreeMfUnit, ThreeMfWriteReport,
626};
627#[path = "io/glb.rs"]
631mod glb;
632pub use glb::{write_glb, GlbReport, GlbSolid, GlbUpAxis, GLB_MAGIC};
633#[path = "io/snapshot.rs"]
637mod snapshot;
638pub use snapshot::{
639 restore_solids, snapshot_resident_solids, snapshot_solids, RestoredSnapshot, RestoredSolid,
640 SNAPSHOT_FORMAT_VERSION,
641};
642#[path = "solvers/linear_algebra.rs"]
643mod solver_linear_algebra;
644#[path = "solvers/sketch_solver.rs"]
645mod sketch_solver;
646pub use sketch_solver::{
647 is_sketch_origin_point_id, sketch_id_key, solve_sketch, solve_sketch_from_json,
648 SketchSolverSettings, SolveSketchRequest, SKETCH_ORIGIN_POINT_ID,
649};
650#[path = "solvers/assembly_solver.rs"]
651mod assembly_solver;
652pub use assembly_solver::{
653 solve_assembly, AssemblyBody, AssemblyMate, AssemblySolution, AssemblySolveOptions, BodyFreedom, BodyPose,
654 LinearAlgebra, MateAlign, MateAxis, MateCurve, MateKind, MatePlane, MateResidualReport,
655 SolveStrategy, SymmetricElement,
656};
657#[path = "solvers/sketch3d_solver.rs"]
661mod sketch3d_solver;
662pub use sketch3d_solver::{
663 sketch3d_constraint_type, solve_sketch3d, solve_sketch3d_doc, solve_sketch3d_from_json,
664 Sketch3dConstraint, Sketch3dConstraintType, Sketch3dDiagnostics, Sketch3dDoc,
665 Sketch3dGeometry, Sketch3dPoint, Sketch3dSolveOptions, SolveSketch3dRequest,
666 SKETCH3D_CONSTRAINT_TYPES,
667};
668#[path = "solvers/assembly_resolve.rs"]
669mod assembly_resolve;
670pub use assembly_resolve::{
671 is_component_reference, resolve_component_point, resolve_edge_selection,
672 resolve_face_selection, resolve_named_selection, resolve_vertex_selection,
673 split_component_namespace, ResolveError, SelectionGeometry,
674};
675#[path = "edit/direct_edit.rs"]
676mod direct_edit;
677pub use direct_edit::{
678 delete_face_and_heal, delete_faces_and_heal, move_faces, offset_freeform_face,
679 offset_revolution_face, offset_ruled_face, offset_sphere_face, offset_torus_face,
680 recut_moved_planes, recut_moved_planes_rigid, resolve_face_by_point, rotate_faces,
681 route_reading, RouteReading,
682};
683pub use direct_edit::{face_refusal_slugs, face_transform_reason, FaceTransformReason};
684pub use direct_edit::{
685 refit_faces_as_one, refit_refusal_phrases, RefitCarrier, RefitReport, RefitSurfaceKind,
686};
687#[path = "healing/sew.rs"]
688mod sew;
689pub use sew::{sew_solid, split_pinched_vertices, SewReport};
690#[path = "meshing/mesh_weld.rs"]
691mod mesh_weld;
692#[path = "meshing/mesh_segment.rs"]
693mod mesh_segment;
694pub use mesh_segment::{
695 mesh_regions_to_brep, segment_mesh_faces, MeshRegion, MeshSegmentation, RegionCarrier,
696 SegmentOptions, UNASSIGNED_REGION,
697};
698
699#[path = "meshing/spherical_union.rs"]
700mod spherical_union;
701pub use spherical_union::reconstruct_spherical_mesh_union;
702
703#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
704pub struct Vec3 {
705 pub x: f64,
706 pub y: f64,
707 pub z: f64,
708}
709
710impl Vec3 {
711 pub fn new(x: f64, y: f64, z: f64) -> Self {
712 Self { x, y, z }
713 }
714 pub fn sub(self, rhs: Self) -> Self {
715 Self::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
716 }
717 pub fn add(self, rhs: Self) -> Self {
718 Self::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
719 }
720 pub fn scale(self, factor: f64) -> Self {
721 Self::new(self.x * factor, self.y * factor, self.z * factor)
722 }
723 pub fn cross(self, rhs: Self) -> Self {
724 Self::new(
725 self.y * rhs.z - self.z * rhs.y,
726 self.z * rhs.x - self.x * rhs.z,
727 self.x * rhs.y - self.y * rhs.x,
728 )
729 }
730 pub fn dot(self, rhs: Self) -> f64 {
731 self.x * rhs.x + self.y * rhs.y + self.z * rhs.z
732 }
733 pub fn length(self) -> f64 {
734 self.dot(self).sqrt()
735 }
736 pub fn length_squared(self) -> f64 {
737 self.dot(self)
738 }
739 pub fn normalized(self) -> Result<Self, String> {
740 let length = self.length();
741 if length <= 1e-12 {
742 return Err("Vec3.normalized: zero-length vector".into());
743 }
744 Ok(self.scale(1.0 / length))
745 }
746 pub fn perpendicular(self) -> Result<Self, String> {
747 let x = self.x.abs();
748 let y = self.y.abs();
749 let z = self.z.abs();
750 let axis = if x <= y && x <= z {
751 Self::new(1.0, 0.0, 0.0)
752 } else if y <= z {
753 Self::new(0.0, 1.0, 0.0)
754 } else {
755 Self::new(0.0, 0.0, 1.0)
756 };
757 self.cross(axis).normalized()
758 }
759}
760
761#[derive(Clone, Debug, Default, Deserialize, Serialize)]
762pub struct Mesh {
763 pub positions: Vec<f64>,
764 pub normals: Vec<f64>,
765 pub indices: Vec<u32>,
766 pub face_ids: Vec<u32>,
767}
768
769impl Mesh {
770 fn push_vertex(&mut self, point: Vec3, normal: Vec3) -> u32 {
771 self.positions.extend([point.x, point.y, point.z]);
772 self.normals.extend([normal.x, normal.y, normal.z]);
773 (self.positions.len() / 3 - 1) as u32
774 }
775
776 fn quad(&mut self, points: [Vec3; 4], normal: Vec3, face_id: u32) {
777 let base = self.push_vertex(points[0], normal);
778 for point in points.iter().skip(1) {
779 self.push_vertex(*point, normal);
780 }
781 self.indices
782 .extend([base, base + 1, base + 2, base, base + 2, base + 3]);
783 self.face_ids.extend([face_id, face_id]);
784 }
785
786 pub fn signed_volume(&self) -> f64 {
787 self.indices
788 .chunks_exact(3)
789 .map(|tri| {
790 let point = |index: u32| {
791 let i = index as usize * 3;
792 Vec3::new(
793 self.positions[i],
794 self.positions[i + 1],
795 self.positions[i + 2],
796 )
797 };
798 point(tri[0]).dot(point(tri[1]).cross(point(tri[2]))) / 6.0
799 })
800 .sum()
801 }
802
803 pub fn validate(&self) -> Result<(), String> {
804 if self.positions.len() % 3 != 0 || self.normals.len() != self.positions.len() {
805 return Err("invalid vertex or normal buffer".into());
806 }
807 self.validate_geometry()
808 }
809
810 pub fn validate_geometry(&self) -> Result<(), String> {
815 if self.positions.len() % 3 != 0 {
816 return Err("invalid vertex buffer".into());
817 }
818 if self.indices.len() % 3 != 0 {
819 return Err("index buffer is not triangular".into());
820 }
821 let count = self.positions.len() / 3;
822 if self.indices.iter().any(|index| *index as usize >= count) {
823 return Err("index outside vertex buffer".into());
824 }
825 if !self.positions.iter().all(|value| value.is_finite()) {
826 return Err("non-finite vertex".into());
827 }
828 Ok(())
829 }
830}
831
832pub fn make_box(size_x: f64, size_y: f64, size_z: f64) -> Mesh {
833 let x = size_x.abs();
834 let y = size_y.abs();
835 let z = size_z.abs();
836 let p = [
837 Vec3::new(0.0, 0.0, 0.0),
838 Vec3::new(x, 0.0, 0.0),
839 Vec3::new(x, y, 0.0),
840 Vec3::new(0.0, y, 0.0),
841 Vec3::new(0.0, 0.0, z),
842 Vec3::new(x, 0.0, z),
843 Vec3::new(x, y, z),
844 Vec3::new(0.0, y, z),
845 ];
846 let mut mesh = Mesh::default();
847 mesh.quad([p[0], p[3], p[2], p[1]], Vec3::new(0.0, 0.0, -1.0), 0);
848 mesh.quad([p[4], p[5], p[6], p[7]], Vec3::new(0.0, 0.0, 1.0), 1);
849 mesh.quad([p[0], p[1], p[5], p[4]], Vec3::new(0.0, -1.0, 0.0), 2);
850 mesh.quad([p[3], p[7], p[6], p[2]], Vec3::new(0.0, 1.0, 0.0), 3);
851 mesh.quad([p[0], p[4], p[7], p[3]], Vec3::new(-1.0, 0.0, 0.0), 4);
852 mesh.quad([p[1], p[2], p[6], p[5]], Vec3::new(1.0, 0.0, 0.0), 5);
853 mesh
854}
855
856pub fn make_cylinder(radius: f64, height: f64, segments: usize) -> Mesh {
857 let radius = radius.abs();
858 let height = height.abs();
859 let segments = segments.max(3);
860 let mut mesh = Mesh::default();
861 for i in 0..segments {
862 let a = std::f64::consts::TAU * i as f64 / segments as f64;
863 let b = std::f64::consts::TAU * (i + 1) as f64 / segments as f64;
864 let (sa, ca) = a.sin_cos();
865 let (sb, cb) = b.sin_cos();
866 let pa = Vec3::new(radius * ca, 0.0, -radius * sa);
867 let pb = Vec3::new(radius * cb, 0.0, -radius * sb);
868 let ta = Vec3::new(pa.x, height, pa.z);
869 let tb = Vec3::new(pb.x, height, pb.z);
870 mesh.quad(
871 [pa, pb, tb, ta],
872 Vec3::new((ca + cb) * 0.5, 0.0, -(sa + sb) * 0.5),
873 0,
874 );
875 let bottom = mesh.push_vertex(Vec3::default(), Vec3::new(0.0, -1.0, 0.0));
876 let bi = mesh.push_vertex(pb, Vec3::new(0.0, -1.0, 0.0));
877 let bj = mesh.push_vertex(pa, Vec3::new(0.0, -1.0, 0.0));
878 mesh.indices.extend([bottom, bi, bj]);
879 mesh.face_ids.push(1);
880 let top = mesh.push_vertex(Vec3::new(0.0, height, 0.0), Vec3::new(0.0, 1.0, 0.0));
881 let ti = mesh.push_vertex(ta, Vec3::new(0.0, 1.0, 0.0));
882 let tj = mesh.push_vertex(tb, Vec3::new(0.0, 1.0, 0.0));
883 mesh.indices.extend([top, ti, tj]);
884 mesh.face_ids.push(2);
885 }
886 mesh
887}
888
889
890mod abi;
891pub use abi::*;
892