1- import initOpenCascade , { OpenCascadeInstance } from "../../bitbybit-dev-occt/bitbybit-dev-occt" ;
1+ import initOpenCascade , { OpenCascadeInstance , TopoDS_Edge } from "../../bitbybit-dev-occt/bitbybit-dev-occt" ;
22import { OccHelper } from "../occ-helper" ;
33import { VectorHelperService } from "../api/vector-helper.service" ;
44import { ShapesHelperService } from "../api/shapes-helper.service" ;
@@ -14,6 +14,12 @@ describe("OCCT shape fix unit tests", () => {
1414 let shapeFix : OCCTShapeFix ;
1515 let occHelper : OccHelper ;
1616
17+ const getEdgeStartAndEndPoints = ( e : TopoDS_Edge ) : { start : number [ ] , end : number [ ] } => {
18+ const startPt = occHelper . edgesService . startPointOnEdge ( { shape : e } ) ;
19+ const endPt = occHelper . edgesService . endPointOnEdge ( { shape : e } ) ;
20+ return { start : startPt , end : endPt } ;
21+ } ;
22+
1723 beforeAll ( async ( ) => {
1824 occt = await initOpenCascade ( ) ;
1925 const vec = new VectorHelperService ( ) ;
@@ -112,5 +118,172 @@ describe("OCCT shape fix unit tests", () => {
112118 edgesOriginal . forEach ( e => e . delete ( ) ) ;
113119 edges . forEach ( e => e . delete ( ) ) ;
114120 } ) ;
121+
122+ it ( "should fix edge orientations along wire when edges have inconsistent directions" , async ( ) => {
123+ // Create edges where the second edge is reversed (end to start instead of start to end)
124+ const edge1 = edge . line ( { start : [ 0 , 0 , 0 ] , end : [ 1 , 0 , 0 ] } ) ;
125+ // This edge goes backwards - from [2,0,0] to [1,0,0] instead of [1,0,0] to [2,0,0]
126+ const edge2 = edge . line ( { start : [ 2 , 0 , 0 ] , end : [ 1 , 0 , 0 ] } ) ;
127+ const edge3 = edge . line ( { start : [ 2 , 0 , 0 ] , end : [ 3 , 0 , 0 ] } ) ;
128+
129+ const wire1 = wire . combineEdgesAndWiresIntoAWire ( {
130+ shapes : [ edge1 , edge2 , edge3 ] ,
131+ } ) ;
132+
133+ const result = shapeFix . fixEdgeOrientationsAlongWire ( { shape : wire1 } ) ;
134+
135+ // Get edges from the fixed wire
136+ const fixedEdges = edge . getEdges ( { shape : result } ) ;
137+ expect ( fixedEdges . length ) . toBe ( 3 ) ;
138+
139+ // Check that edges are now properly oriented along the wire
140+ const edge1Points = getEdgeStartAndEndPoints ( fixedEdges [ 0 ] ) ;
141+ const edge2Points = getEdgeStartAndEndPoints ( fixedEdges [ 1 ] ) ;
142+ const edge3Points = getEdgeStartAndEndPoints ( fixedEdges [ 2 ] ) ;
143+
144+ // Each edge's end should connect to the next edge's start
145+ expect ( edge1Points . end [ 0 ] ) . toBeCloseTo ( edge2Points . start [ 0 ] , 5 ) ;
146+ expect ( edge1Points . end [ 1 ] ) . toBeCloseTo ( edge2Points . start [ 1 ] , 5 ) ;
147+ expect ( edge1Points . end [ 2 ] ) . toBeCloseTo ( edge2Points . start [ 2 ] , 5 ) ;
148+
149+ expect ( edge2Points . end [ 0 ] ) . toBeCloseTo ( edge3Points . start [ 0 ] , 5 ) ;
150+ expect ( edge2Points . end [ 1 ] ) . toBeCloseTo ( edge3Points . start [ 1 ] , 5 ) ;
151+ expect ( edge2Points . end [ 2 ] ) . toBeCloseTo ( edge3Points . start [ 2 ] , 5 ) ;
152+
153+ edge1 . delete ( ) ;
154+ edge2 . delete ( ) ;
155+ edge3 . delete ( ) ;
156+ wire1 . delete ( ) ;
157+ result . delete ( ) ;
158+ fixedEdges . forEach ( e => e . delete ( ) ) ;
159+ } ) ;
160+
161+ it ( "should preserve wire when edges already have correct orientations" , async ( ) => {
162+ // Create properly oriented edges
163+ const edge1 = edge . line ( { start : [ 0 , 0 , 0 ] , end : [ 1 , 0 , 0 ] } ) ;
164+ const edge2 = edge . line ( { start : [ 1 , 0 , 0 ] , end : [ 2 , 0 , 0 ] } ) ;
165+ const edge3 = edge . line ( { start : [ 2 , 0 , 0 ] , end : [ 3 , 0 , 0 ] } ) ;
166+
167+ const wire1 = wire . combineEdgesAndWiresIntoAWire ( {
168+ shapes : [ edge1 , edge2 , edge3 ] ,
169+ } ) ;
170+
171+ const result = shapeFix . fixEdgeOrientationsAlongWire ( { shape : wire1 } ) ;
172+
173+ const fixedEdges = edge . getEdges ( { shape : result } ) ;
174+ expect ( fixedEdges . length ) . toBe ( 3 ) ;
175+
176+ // Verify edges maintain correct orientation
177+ const edge1Points = getEdgeStartAndEndPoints ( fixedEdges [ 0 ] ) ;
178+ const edge2Points = getEdgeStartAndEndPoints ( fixedEdges [ 1 ] ) ;
179+ const edge3Points = getEdgeStartAndEndPoints ( fixedEdges [ 2 ] ) ;
180+
181+ expect ( edge1Points . start ) . toEqual ( [ 0 , 0 , 0 ] ) ;
182+ expect ( edge1Points . end ) . toEqual ( [ 1 , 0 , 0 ] ) ;
183+ expect ( edge2Points . start ) . toEqual ( [ 1 , 0 , 0 ] ) ;
184+ expect ( edge2Points . end ) . toEqual ( [ 2 , 0 , 0 ] ) ;
185+ expect ( edge3Points . start ) . toEqual ( [ 2 , 0 , 0 ] ) ;
186+ expect ( edge3Points . end ) . toEqual ( [ 3 , 0 , 0 ] ) ;
187+
188+ edge1 . delete ( ) ;
189+ edge2 . delete ( ) ;
190+ edge3 . delete ( ) ;
191+ wire1 . delete ( ) ;
192+ result . delete ( ) ;
193+ fixedEdges . forEach ( e => e . delete ( ) ) ;
194+ } ) ;
195+
196+ it ( "should fix edge orientations in a closed wire" , async ( ) => {
197+ // Create a closed triangle with one reversed edge
198+ const edge1 = edge . line ( { start : [ 0 , 0 , 0 ] , end : [ 1 , 0 , 0 ] } ) ;
199+ // Reversed edge
200+ const edge2 = edge . line ( { start : [ 0.5 , 1 , 0 ] , end : [ 1 , 0 , 0 ] } ) ;
201+ const edge3 = edge . line ( { start : [ 0.5 , 1 , 0 ] , end : [ 0 , 0 , 0 ] } ) ;
202+
203+ const wire1 = wire . combineEdgesAndWiresIntoAWire ( {
204+ shapes : [ edge1 , edge2 , edge3 ] ,
205+ } ) ;
206+
207+ expect ( occHelper . wiresService . isWireClosed ( { shape : wire1 } ) ) . toBe ( true ) ;
208+
209+ const result = shapeFix . fixEdgeOrientationsAlongWire ( { shape : wire1 } ) ;
210+
211+ expect ( occHelper . wiresService . isWireClosed ( { shape : result } ) ) . toBe ( true ) ;
212+
213+ const fixedEdges = edge . getEdges ( { shape : result } ) ;
214+ expect ( fixedEdges . length ) . toBe ( 3 ) ;
215+
216+ // Check connectivity of fixed edges
217+ const edge1Points = getEdgeStartAndEndPoints ( fixedEdges [ 0 ] ) ;
218+ const edge2Points = getEdgeStartAndEndPoints ( fixedEdges [ 1 ] ) ;
219+ const edge3Points = getEdgeStartAndEndPoints ( fixedEdges [ 2 ] ) ;
220+
221+ expect ( edge1Points . end [ 0 ] ) . toBeCloseTo ( edge2Points . start [ 0 ] , 5 ) ;
222+ expect ( edge1Points . end [ 1 ] ) . toBeCloseTo ( edge2Points . start [ 1 ] , 5 ) ;
223+ expect ( edge2Points . end [ 0 ] ) . toBeCloseTo ( edge3Points . start [ 0 ] , 5 ) ;
224+ expect ( edge2Points . end [ 1 ] ) . toBeCloseTo ( edge3Points . start [ 1 ] , 5 ) ;
225+ expect ( edge3Points . end [ 0 ] ) . toBeCloseTo ( edge1Points . start [ 0 ] , 5 ) ;
226+ expect ( edge3Points . end [ 1 ] ) . toBeCloseTo ( edge1Points . start [ 1 ] , 5 ) ;
227+
228+ edge1 . delete ( ) ;
229+ edge2 . delete ( ) ;
230+ edge3 . delete ( ) ;
231+ wire1 . delete ( ) ;
232+ result . delete ( ) ;
233+ fixedEdges . forEach ( e => e . delete ( ) ) ;
234+ } ) ;
235+
236+ it ( "should fix edge orientations with arc edges" , async ( ) => {
237+ const edge1 = edge . line ( { start : [ 0 , 0 , 0 ] , end : [ 1 , 0 , 0 ] } ) ;
238+ // Arc going backwards
239+ const arcEdge = edge . arcThroughThreePoints ( { start : [ 2 , 0 , 0 ] , middle : [ 1.5 , 0.5 , 0 ] , end : [ 1 , 0 , 0 ] } ) ;
240+ const edge3 = edge . line ( { start : [ 2 , 0 , 0 ] , end : [ 3 , 0 , 0 ] } ) ;
241+
242+ const wire1 = wire . combineEdgesAndWiresIntoAWire ( {
243+ shapes : [ edge1 , arcEdge , edge3 ] ,
244+ } ) ;
245+
246+ const result = shapeFix . fixEdgeOrientationsAlongWire ( { shape : wire1 } ) ;
247+
248+ const fixedEdges = edge . getEdges ( { shape : result } ) ;
249+ expect ( fixedEdges . length ) . toBe ( 3 ) ;
250+
251+ // Check that edges are connected properly
252+ const edge1Points = getEdgeStartAndEndPoints ( fixedEdges [ 0 ] ) ;
253+ const edge2Points = getEdgeStartAndEndPoints ( fixedEdges [ 1 ] ) ;
254+ const edge3Points = getEdgeStartAndEndPoints ( fixedEdges [ 2 ] ) ;
255+
256+ expect ( edge1Points . end [ 0 ] ) . toBeCloseTo ( edge2Points . start [ 0 ] , 5 ) ;
257+ expect ( edge2Points . end [ 0 ] ) . toBeCloseTo ( edge3Points . start [ 0 ] , 5 ) ;
258+
259+ edge1 . delete ( ) ;
260+ arcEdge . delete ( ) ;
261+ edge3 . delete ( ) ;
262+ wire1 . delete ( ) ;
263+ result . delete ( ) ;
264+ fixedEdges . forEach ( e => e . delete ( ) ) ;
265+ } ) ;
266+
267+ it ( "should handle a single edge wire" , async ( ) => {
268+ const edge1 = edge . line ( { start : [ 0 , 0 , 0 ] , end : [ 1 , 0 , 0 ] } ) ;
269+
270+ const wire1 = wire . combineEdgesAndWiresIntoAWire ( {
271+ shapes : [ edge1 ] ,
272+ } ) ;
273+
274+ const result = shapeFix . fixEdgeOrientationsAlongWire ( { shape : wire1 } ) ;
275+
276+ const fixedEdges = edge . getEdges ( { shape : result } ) ;
277+ expect ( fixedEdges . length ) . toBe ( 1 ) ;
278+
279+ const edgePoints = getEdgeStartAndEndPoints ( fixedEdges [ 0 ] ) ;
280+ expect ( edgePoints . start ) . toEqual ( [ 0 , 0 , 0 ] ) ;
281+ expect ( edgePoints . end ) . toEqual ( [ 1 , 0 , 0 ] ) ;
282+
283+ edge1 . delete ( ) ;
284+ wire1 . delete ( ) ;
285+ result . delete ( ) ;
286+ fixedEdges . forEach ( e => e . delete ( ) ) ;
287+ } ) ;
115288} ) ;
116289
0 commit comments