@eturnity/eturnity_maths 7.2.3 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_maths",
3
- "version": "7.2.3",
3
+ "version": "7.4.0",
4
4
  "author": "Eturnity Team",
5
5
  "main": "src/index.js",
6
6
  "private": false,
package/src/config.js CHANGED
@@ -5,7 +5,7 @@ export const snapToPointTolerance = 15
5
5
  export const snapToIntersectionPointTolerance = 15
6
6
  export const snapToLineTolerance = 10
7
7
  export const distanceToCloseNode = 70
8
- export const mmTolerance=50
8
+ export const mmTolerance=1
9
9
  export const earthRadius=6371008
10
10
 
11
11
  export const layerColors = {
package/src/geometry.js CHANGED
@@ -15,13 +15,22 @@ import {Point} from './objects/Point'
15
15
  import {Line} from './objects/Line'
16
16
  import concaveman from 'concaveman'
17
17
 
18
- export function getConcaveOutline(selectedPanels,onPanelOutline){
18
+ export function getConcaveOutlines(selectedPanels,onePanelOutline){
19
+ let buckets=groupAdjacentObjects(selectedPanels)
20
+ const outlines = []
21
+ for(let bucketIndex=0;bucketIndex<buckets.length;bucketIndex++){
22
+ outlines.push(getConcaveOutline(selectedPanels.filter((p,i)=>buckets[bucketIndex].includes(i)),onePanelOutline))
23
+ }
24
+ return {outlines,buckets}
25
+ }
26
+
27
+ export function getConcaveOutline(selectedPanels,onePanelOutline){
19
28
  const points = selectedPanels.reduce((acc, cur) => {
20
29
  acc.push(...cur.outline.map((p) => [p.x, p.y]))
21
30
  return acc
22
31
  }, [])
23
- let AB = getDistanceBetweenPoints(onPanelOutline[0], onPanelOutline[1])
24
- let AD = getDistanceBetweenPoints(onPanelOutline[0], onPanelOutline[3])
32
+ let AB = getDistanceBetweenPoints(onePanelOutline[0], onePanelOutline[1])
33
+ let AD = getDistanceBetweenPoints(onePanelOutline[0], onePanelOutline[3])
25
34
  let longEdgeLength = Math.max(AB, AD)+100
26
35
  var concaveResult = concaveman(points, 1, longEdgeLength)
27
36
  concaveResult.pop()
@@ -719,9 +728,54 @@ export function get3DDistanceBetweenPoints(firstPoint, secondPoint) {
719
728
  const det = (B.x - A.x) * (C.y - A.y) - (C.x - A.x) * (B.y - A.y)
720
729
  return det < 0
721
730
  }
722
-
731
+ export function groupAdjacentObjects(objects){
732
+ if(!objects || objects.length==0) return []
733
+ // objects with 2D indexes
734
+ // Check if the objects form an adjacent group
735
+ let numberOfObjects=objects.length
736
+ let indexList=Array.from({length: numberOfObjects}, (e, i)=> i)
737
+ let buckets = []
738
+ let inBucket=0
739
+ while (inBucket<objects.length)
740
+ {
741
+ let detatchedIndex=indexList.find(i=>!buckets.flat().includes(i))
742
+ if(detatchedIndex==null) break
743
+ let queue = [detatchedIndex]
744
+ let visited = []
745
+ while (queue.length > 0) {
746
+ const currentObjectIndex = queue.pop()
747
+ if (visited.indexOf(currentObjectIndex) == -1) {
748
+ //if next queued index hasn't been visited, we mark it as visited and we collect all neighbourg to queue
749
+ visited.push(currentObjectIndex)
750
+ let x = objects[currentObjectIndex].index[0]
751
+ let y = objects[currentObjectIndex].index[1]
752
+ const left = objects.findIndex(
753
+ (o) => o.index[0] == x - 1 && o.index[1] == y
754
+ )
755
+ const right = objects.findIndex(
756
+ (o) => o.index[0] == x + 1 && o.index[1] == y
757
+ )
758
+ const top = objects.findIndex(
759
+ (o) => o.index[0] == x && o.index[1] == y - 1
760
+ )
761
+ const bottom = objects.findIndex(
762
+ (o) => o.index[0] == x && o.index[1] == y + 1
763
+ )
764
+ if (left != -1 && visited.indexOf(left) == -1) queue.push(left)
765
+ if (right != -1 && visited.indexOf(right) == -1) queue.push(right)
766
+ if (top != -1 && visited.indexOf(top) == -1) queue.push(top)
767
+ if (bottom != -1 && visited.indexOf(bottom) == -1) queue.push(bottom)
768
+ }
769
+ }
770
+ inBucket+=visited.length
771
+ buckets.push(visited)
772
+ }
773
+
774
+ return buckets
775
+ }
723
776
  // Function to check if two indexes are adjacent
724
777
  export function areAdjacent(objects) {
778
+ if(!objects || objects.length==0) return false
725
779
  // objects with 2D indexes
726
780
  // Check if the objects form an adjacent group
727
781
  let visited = []
@@ -73,6 +73,7 @@ export function logicOperationOnPolygons(outline1,outline2,mode='intersect')
73
73
  return {outline:[p,fig2[(index+1)%fig2.length]]}
74
74
  })
75
75
  let intersections = getIntersections({outline:fig1}, edges)
76
+
76
77
  //2. gather all nodes+intersection in a list[[x,y],[x,y]]
77
78
  const nodeList = getNodeList(intersections, edges, {outline:fig1})
78
79
  //3. generate all edges not cut, those cut and those from construction polyline
@@ -86,9 +87,13 @@ export function logicOperationOnPolygons(outline1,outline2,mode='intersect')
86
87
  1
87
88
  )
88
89
  //4. run planar-face-discovery to get all cycles and rebuild our polygons
89
- const outlineList = getOutlineList(nodeList, edgeList)
90
-
91
- return filterPolygons(outlineList, fig1, fig2, mode)
90
+ try{
91
+ const outlineList = getOutlineList(nodeList, edgeList)
92
+ return filterPolygons(outlineList, fig1, fig2, mode)
93
+ }catch(err){
94
+ console.error("error with getOutlineList",nodeList, edgeList,err)
95
+ return []
96
+ }
92
97
  }
93
98
 
94
99
  function filterPolygons(polygons, fig1, fig2, mode) {
@@ -166,6 +166,7 @@ export class Polygon {
166
166
  extraSerialization.mountingData = this.mountingData?{...this.mountingData}:null
167
167
  extraSerialization.modules = modules
168
168
  extraSerialization.needsOptimisation = this.needsOptimisation
169
+ extraSerialization.priority = this.priority
169
170
 
170
171
  } else if (this.layer == 'panel') {
171
172
  extraSerialization.index = this.index
@@ -210,27 +211,7 @@ export class Polygon {
210
211
  if (!this.userDeactivatedPanels) {
211
212
  this.userDeactivatedPanels = []
212
213
  }
213
- const modules = this.panels.map((p) => {
214
- return {
215
- index: p.index,
216
- outline: p.outline.map((v) => [v.x, v.y, v.z]),
217
- status: p.status || "active",
218
- clipped: p.clipped === undefined ? false : p.clipped
219
- }
220
- })
221
- const user_deactivated_modules = this.userDeactivatedPanels.map((p) => {
222
- return {
223
- index: p.index,
224
- outline: p.outline.map((v) => [v.x, v.y, v.z]),
225
- }
226
- })
227
- user_deactivated_modules.forEach(p=>{
228
- modules.push({
229
- ...p,
230
- status: p.status || "user_deactivated",
231
- clipped: p.clipped === undefined ? false : p.clipped
232
- })
233
- })
214
+ const modules = this.data.modules
234
215
  return {
235
216
  module_field_uuid: this.id,
236
217
  roof_uuid: this.roof.id,
@@ -16,9 +16,10 @@ import {
16
16
  isAlmostSamePoint2D,
17
17
  getDistanceBetweenPoints
18
18
  } from '../../geometry'
19
- import { maximumGapLimit } from '../../config'
19
+ import { maximumGapLimit, mmTolerance } from '../../config'
20
20
  import { SVD } from 'svd-js'
21
21
  import {updateMarginOutlinePolygon} from './AddMargin'
22
+ import { isSelfIntersecting } from '../../intersectionPolygon'
22
23
 
23
24
  //This function calculate derived field from polygon outline and margin outline
24
25
  export function updateComputedGeometryState(state) {
@@ -100,28 +101,41 @@ export function updateComputedGeometryPolygon(polygon) {
100
101
  export function calculateValidOutlineFromPolygon(outline){
101
102
  //check if two nodes are same
102
103
  const nodeIndexToSplit=[]
104
+ const nodesToRemove=[]
103
105
  for(let k=0;k<outline.length-1;k++){
104
106
  for(let i=k+1;i<outline.length;i++){
105
- if(isAlmostSamePoint2D(outline[k],outline[i],100)){
106
- nodeIndexToSplit.push([k,i])
107
+ if(isAlmostSamePoint2D(outline[k],outline[i],2*mmTolerance)){
108
+ if(i==k+1){
109
+ nodesToRemove.push(i)
110
+ }else{
111
+ nodeIndexToSplit.push([k,i])
112
+ }
107
113
  }
108
114
  }
109
115
  }
116
+
110
117
  for(let coupleToSplit of nodeIndexToSplit){
111
118
  const A = outline[(coupleToSplit[0]-1+outline.length)%outline.length]
112
119
  const B = outline[coupleToSplit[0]]
113
120
  const C = outline[(coupleToSplit[0]+1)%outline.length]
114
- let v = normalizedVectorTowardInsideAngle(A,B,C)
115
- // let v0=normalizeVector(substractVector())
121
+ const D = outline[(coupleToSplit[1]-1+outline.length)%outline.length]
122
+ const E = outline[coupleToSplit[1]]
123
+ const F = outline[(coupleToSplit[1]+1)%outline.length]
124
+ let u = normalizedVectorTowardInsideAngle(A,B,C)
125
+ let v = normalizedVectorTowardInsideAngle(D,E,F)
126
+
116
127
  outline[coupleToSplit[0]] = {
117
- ...addVector(multiplyVector(-50,v),B),
128
+ ...addVector(multiplyVector(-mmTolerance,u),B),
118
129
  z:outline[coupleToSplit[0]].z
119
130
  }
120
131
  outline[coupleToSplit[1]] = {
121
- ...addVector(multiplyVector(50,v),B),
132
+ ...addVector(multiplyVector(mmTolerance,v),E),
122
133
  z:outline[coupleToSplit[1]].z
123
134
  }
124
135
  }
136
+ for(let index=nodesToRemove.length-1;index>=0;index--){
137
+ outline.splice(nodesToRemove[index],1)
138
+ }
125
139
  return outline
126
140
  }
127
141