rawanessam commited on
Commit
192416d
·
verified ·
1 Parent(s): 2a18c3b

Update rendering/floorplan.py

Browse files
Files changed (1) hide show
  1. rendering/floorplan.py +192 -975
rendering/floorplan.py CHANGED
@@ -1,987 +1,204 @@
1
- from panda3d.egg import *
2
- from panda3d.core import *
3
- from obj2egg import ObjMaterial
4
- from copy import deepcopy
5
  import numpy as np
6
  import cv2
7
  import copy
8
-
9
  def calcDistance(point_1, point_2):
10
- return pow(pow(point_1[0] - point_2[0], 2) + pow(point_1[1] - point_2[1], 2), 0.5)
11
-
12
- def calcLineDim(line, lineWidth = -1):
13
- if abs(line[0][0] - line[1][0]) > abs(line[0][1] - line[1][1]):
14
- if lineWidth < 0 or abs(line[0][1] - line[1][1]) <= lineWidth:
15
- return 0
16
- pass
17
- elif abs(line[0][0] - line[1][0]) < abs(line[0][1] - line[1][1]):
18
- if lineWidth < 0 or abs(line[0][0] - line[1][0]) <= lineWidth:
19
- return 1
20
- else:
21
- return -1
22
-
23
  class Floorplan():
24
- def __init__(self, filename):
25
- self.wallWidth = 0.005
26
- self.wallHeight = 0.3
27
- self.doorWidth = self.wallWidth
28
- self.doorHeight = self.wallHeight * 0.8
29
- self.windowWidth = self.wallWidth + 0.0001
30
- self.windowHeight = self.wallHeight * 0.5
31
- self.windowOffset = self.wallHeight * 0.4
32
- self.filename = filename
33
-
34
- self.floorMat = ObjMaterial()
35
- #self.floorMat.filename = self.filename + '.png'
36
- self.floorMat.name = 'floor'
37
- self.floorMat.put('map_Kd', self.filename + '.png')
38
-
39
- self.ceilingMat = ObjMaterial()
40
- self.ceilingMat.name = 'ceiling'
41
- self.ceilingMat.put('map_Kd', 'data/ceiling.jpg')
42
-
43
- self.wallMats = []
44
- wallMat_1 = ObjMaterial()
45
- wallMat_1.name = 'wall_1'
46
- wallMat_1.put('map_Kd', 'data/bedroom_wall.jpg')
47
- wallMat_2 = ObjMaterial()
48
- wallMat_2.name = 'wall_2'
49
- wallMat_2.put('map_Kd', 'data/kitchen_wall.jpg')
50
- wallMat_3 = ObjMaterial()
51
- wallMat_3.name = 'wall_3'
52
- wallMat_3.put('map_Kd', 'data/dining_wall.jpg')
53
- wallMat_4 = ObjMaterial()
54
- wallMat_4.name = 'wall_4'
55
- wallMat_4.put('map_Kd', 'data/bathroom_wall.jpg')
56
- wallMat_5 = ObjMaterial()
57
- wallMat_5.name = 'wall_5'
58
- wallMat_5.put('map_Kd', 'data/wall.jpg')
59
-
60
- self.wallMats.append(wallMat_3)
61
- self.wallMats.append(wallMat_2)
62
- self.wallMats.append(wallMat_1)
63
- self.wallMats.append(wallMat_4)
64
- self.wallMats.append(wallMat_4)
65
- self.wallMats.append(wallMat_1)
66
- self.wallMats.append(wallMat_5)
67
- self.wallMats.append(wallMat_2)
68
- self.wallMats.append(wallMat_4)
69
- self.wallMats.append(wallMat_5)
70
- self.wallMats.append(wallMat_5)
71
-
72
-
73
- self.doorMat = ObjMaterial()
74
- self.doorMat.name = 'door'
75
- self.doorMat.put('map_Kd', 'data/door.jpg')
76
-
77
- self.windowMat = ObjMaterial()
78
- self.windowMat.name = 'window'
79
- self.windowMat.put('map_Kd', 'data/window.jpg')
80
-
81
- self.iconNodes = {}
82
- self.iconNodes['cooking_counter'] = base.loader.loadModel('data/cooking_counter.egg')
83
- self.iconNodes['bathtub'] = base.loader.loadModel('data/bathtub.egg')
84
- self.iconNodes['toilet'] = base.loader.loadModel('data/toilet.egg')
85
- self.iconNodes['washing_basin'] = base.loader.loadModel('data/washing_basin.egg')
86
- return
87
-
88
-
89
- def read(self):
90
- floorplanFile = open(self.filename + '.txt', 'r')
91
- self.walls = []
92
- self.doors = []
93
- self.icons = []
94
- self.wallsInt = []
95
- for line in floorplanFile.readlines():
96
- line = line.strip()
97
- values = line.split('\t')
98
- if len(values) == 2:
99
- self.width = float(values[0])
100
- self.height = float(values[1])
101
- self.maxDim = max(self.width, self.height)
102
- elif len(values) == 6:
103
- wall = []
104
- for i in xrange(4):
105
- wall.append(float(values[i]))
106
- continue
107
- lineDim = calcLineDim(((wall[0], wall[1]), (wall[2], wall[3])))
108
- wall[lineDim], wall[2 + lineDim] = min(wall[lineDim], wall[2 + lineDim]), max(wall[lineDim], wall[2 + lineDim])
109
- wall[1 - lineDim] = wall[3 - lineDim] = (wall[1 - lineDim] + wall[3 - lineDim]) / 2
110
- wall.append(int(values[4]) - 1)
111
- wall.append(int(values[5]) - 1)
112
- for pointIndex in xrange(2):
113
- wall[pointIndex * 2 + 0] /= self.maxDim
114
- wall[pointIndex * 2 + 1] /= self.maxDim
115
- continue
116
- self.walls.append(wall)
117
-
118
- wallInt = []
119
- for i in xrange(4):
120
- wallInt.append(int(values[i]))
121
- continue
122
- wallInt[lineDim], wallInt[2 + lineDim] = min(wallInt[lineDim], wallInt[2 + lineDim]), max(wallInt[lineDim], wallInt[2 + lineDim])
123
- self.wallsInt.append(wallInt)
124
- elif len(values) == 7:
125
- item = []
126
- for i in xrange(4):
127
- item.append(float(values[i]))
128
-
129
- for pointIndex in xrange(2):
130
- item[pointIndex * 2 + 0] /= self.maxDim
131
- item[pointIndex * 2 + 1] /= self.maxDim
132
- continue
133
-
134
- if values[4] == 'door':
135
- self.doors.append(item)
136
- else:
137
- item.append(values[4])
138
- self.icons.append(item)
139
- pass
140
- pass
141
- continue
142
- return
143
-
144
- def generateFloor(self, data):
145
- floorGroup = EggGroup('floor')
146
- data.addChild(floorGroup)
147
-
148
- vp = EggVertexPool('floor_vertex')
149
- floorGroup.addChild(vp)
150
-
151
-
152
- exteriorWalls = []
153
- for wall in self.walls:
154
- if wall[4] == 10 or wall[5] == 10:
155
- exteriorWalls.append(copy.deepcopy(wall))
156
- pass
157
- continue
158
-
159
-
160
- exteriorOpenings = []
161
- for wall in exteriorWalls:
162
- lineDim = calcLineDim((wall[:2], wall[2:4]))
163
- for doorIndex, door in enumerate(self.doors):
164
- if calcLineDim((door[:2], door[2:4])) != lineDim:
165
- continue
166
- if door[lineDim] >= wall[lineDim] and door[2 + lineDim] <= wall[2 + lineDim] and abs(door[1 - lineDim] - wall[1 - lineDim]) <= self.wallWidth:
167
- exteriorOpenings.append(doorIndex)
168
- pass
169
- continue
170
- continue
171
-
172
- minDistance = 10000
173
- mainDoorIndex = -1
174
- for icon in self.icons:
175
- if icon[4] == 'entrance':
176
- for doorIndex in exteriorOpenings:
177
- door = self.doors[doorIndex]
178
- distance = pow(pow((door[0] + door[2]) / 2 - (icon[0] + icon[2]) / 2, 2) + pow((door[1] + door[3]) / 2 - (icon[1] + icon[3]) / 2, 2), 0.5)
179
- if distance < minDistance:
180
- minDistance = distance
181
- mainDoorIndex = doorIndex
182
- pass
183
- continue
184
- break
185
- continue
186
-
187
- self.startCameraPos = [0.5, -0.5, self.wallHeight * 0.5]
188
- self.startTarget = [0.5, 0.5, self.wallHeight * 0.5]
189
- if mainDoorIndex >= 0:
190
- mainDoor = self.doors[mainDoorIndex]
191
- lineDim = calcLineDim((mainDoor[:2], mainDoor[2:4]))
192
- fixedValue = (mainDoor[1 - lineDim] + mainDoor[3 - lineDim]) / 2
193
- imageSize = [self.width / self.maxDim, self.height / self.maxDim]
194
- side = int(fixedValue < imageSize[1 - lineDim] * 0.5) * 2 - 1
195
- self.startCameraPos[lineDim] = (mainDoor[lineDim] + mainDoor[2 + lineDim]) / 2
196
- self.startTarget[lineDim] = (mainDoor[lineDim] + mainDoor[2 + lineDim]) / 2
197
- self.startCameraPos[1 - lineDim] = fixedValue - 0.5 * side
198
- self.startTarget[1 - lineDim] = fixedValue + 0.5 * side
199
-
200
- self.startCameraPos[0] = 1 - self.startCameraPos[0]
201
- self.startTarget[0] = 1 - self.startTarget[0]
202
- pass
203
-
204
- newDoors = []
205
- self.windows = []
206
- for doorIndex, door in enumerate(self.doors):
207
- if doorIndex == mainDoorIndex or doorIndex not in exteriorOpenings:
208
- newDoors.append(door)
209
- else:
210
- self.windows.append(door)
211
- pass
212
- continue
213
- self.doors = newDoors
214
-
215
-
216
- exteriorWallLoops = []
217
- visitedMask = {}
218
- gap = 5.0 / self.maxDim
219
- for wallIndex, wall in enumerate(exteriorWalls):
220
- if wallIndex in visitedMask:
221
- continue
222
- visitedMask[wallIndex] = True
223
- exteriorWallLoop = []
224
- exteriorWallLoop.append(wall)
225
- for loopWall in exteriorWallLoop:
226
- for neighborWallIndex, neighborWall in enumerate(exteriorWalls):
227
- if neighborWallIndex in visitedMask:
228
- continue
229
- #if calcDistance(neighborWall[:2], loopWall[:2]) < gap or calcDistance(neighborWall[2:4], loopWall[:2]) < gap or calcDistance(neighborWall[:2], loopWall[2:4]) < gap or calcDistance(neighborWall[2:4], loopWall[2:4]) < gap:
230
- if calcDistance(neighborWall[:2], loopWall[2:4]) < gap:
231
- exteriorWallLoop.append(neighborWall)
232
- visitedMask[neighborWallIndex] = True
233
- break
234
- elif calcDistance(neighborWall[2:4], loopWall[2:4]) < gap:
235
- neighborWall[0], neighborWall[2] = neighborWall[2], neighborWall[0]
236
- neighborWall[1], neighborWall[3] = neighborWall[3], neighborWall[1]
237
- exteriorWallLoop.append(neighborWall)
238
- visitedMask[neighborWallIndex] = True
239
- break
240
- continue
241
- continue
242
- exteriorWallLoops.append(exteriorWallLoop)
243
- continue
244
-
245
-
246
- for exteriorWallLoop in exteriorWallLoops:
247
- poly = EggPolygon()
248
- floorGroup.addChild(poly)
249
-
250
- poly.setTexture(self.floorMat.getEggTexture())
251
- poly.setMaterial(self.floorMat.getEggMaterial())
252
-
253
- for wallIndex, wall in enumerate(exteriorWallLoop):
254
- if wallIndex == 0:
255
- v = EggVertex()
256
- v.setPos(Point3D(1 - wall[0], wall[1], 0))
257
- v.setUv(Point2D(wall[0] * self.maxDim / self.width, 1 - wall[1] * self.maxDim / self.height))
258
- poly.addVertex(vp.addVertex(v))
259
- else:
260
- v = EggVertex()
261
- v.setPos(Point3D(1 - (wall[0] + exteriorWallLoop[wallIndex - 1][2]) / 2, (wall[1] + exteriorWallLoop[wallIndex - 1][3]) / 2, 0))
262
- v.setUv(Point2D((wall[0] + exteriorWallLoop[wallIndex - 1][2]) / 2 * self.maxDim / self.width, 1 - (wall[1] + exteriorWallLoop[wallIndex - 1][3]) / 2 * self.maxDim / self.height))
263
- poly.addVertex(vp.addVertex(v))
264
- pass
265
- if wallIndex == len(exteriorWallLoop) - 1:
266
- v = EggVertex()
267
- v.setPos(Point3D(1 - wall[2], wall[3], 0))
268
- v.setUv(Point2D(wall[2] * self.maxDim / self.width, 1 - wall[3] * self.maxDim / self.height))
269
- poly.addVertex(vp.addVertex(v))
270
- pass
271
- continue
272
- continue
273
-
274
-
275
- ceilingGroup = EggGroup('ceiling')
276
- data.addChild(ceilingGroup)
277
-
278
- vp = EggVertexPool('ceiling_vertex')
279
- ceilingGroup.addChild(vp)
280
-
281
- for exteriorWallLoop in exteriorWallLoops:
282
- poly = EggPolygon()
283
- ceilingGroup.addChild(poly)
284
-
285
- poly.setTexture(self.ceilingMat.getEggTexture())
286
- poly.setMaterial(self.ceilingMat.getEggMaterial())
287
-
288
- for wallIndex, wall in enumerate(exteriorWallLoop):
289
- if wallIndex == 0:
290
- v = EggVertex()
291
- v.setPos(Point3D(1 - wall[0], wall[1], self.wallHeight))
292
- v.setUv(Point2D(wall[0], 1 - wall[1]))
293
- poly.addVertex(vp.addVertex(v))
294
- else:
295
- v = EggVertex()
296
- v.setPos(Point3D(1 - (wall[0] + exteriorWallLoop[wallIndex - 1][2]) / 2, (wall[1] + exteriorWallLoop[wallIndex - 1][3]) / 2, self.wallHeight))
297
- v.setUv(Point2D((wall[0] + exteriorWallLoop[wallIndex - 1][2]) / 2, 1 - (wall[1] + exteriorWallLoop[wallIndex - 1][3]) / 2))
298
- poly.addVertex(vp.addVertex(v))
299
- pass
300
- if wallIndex == len(exteriorWallLoop) - 1:
301
- v = EggVertex()
302
- v.setPos(Point3D(1 - wall[2], wall[3], self.wallHeight))
303
- v.setUv(Point2D(wall[2], 1 - wall[3]))
304
- poly.addVertex(vp.addVertex(v))
305
- pass
306
- continue
307
- continue
308
-
309
- return
310
-
311
-
312
- def generateWalls(self, data):
313
-
314
- wallsGroup = EggGroup('walls')
315
- data.addChild(wallsGroup)
316
-
317
- vp = EggVertexPool('wall_vertex')
318
- data.addChild(vp)
319
-
320
- for wallIndex, wall in enumerate(self.walls):
321
- wallGroup = EggGroup('wall')
322
- wallsGroup.addChild(wallGroup)
323
- lineDim = calcLineDim((wall[:2], wall[2:4]))
324
- # if lineDim == 0:
325
- # if wall[lineDim] < wall[2 + lineDim]:
326
- # deltas = (-self.wallWidth, self.wallWidth, self.wallWidth, self.wallWidth)
327
- # else:
328
- # deltas = (self.wallWidth, self.wallWidth, -self.wallWidth, self.wallWidth)
329
- # pass
330
- # else:
331
- # if wall[lineDim] < wall[2 + lineDim]:
332
- # deltas = (self.wallWidth, -self.wallWidth, self.wallWidth, self.wallWidth)
333
- # else:
334
- # deltas = (self.wallWidth, self.wallWidth, self.wallWidth, -self.wallWidth)
335
- # pass
336
- # pass
337
-
338
- #print(self.wallsInt[wallIndex])
339
- #print(wall)
340
- if lineDim == 0:
341
- deltas = (0, self.wallWidth)
342
- else:
343
- deltas = (self.wallWidth, 0)
344
- pass
345
-
346
- poly = EggPolygon()
347
- wallGroup.addChild(poly)
348
-
349
- if lineDim == 0:
350
- poly.setTexture(self.wallMats[wall[4]].getEggTexture())
351
- poly.setMaterial(self.wallMats[wall[4]].getEggMaterial())
352
- else:
353
- poly.setTexture(self.wallMats[wall[5]].getEggTexture())
354
- poly.setMaterial(self.wallMats[wall[5]].getEggMaterial())
355
- pass
356
-
357
-
358
- values = [wall[lineDim] - self.wallWidth + 0.0001, wall[2 + lineDim] + self.wallWidth - 0.0001]
359
- for door in self.doors:
360
- if calcLineDim((door[:2], door[2:4])) != lineDim:
361
- continue
362
- if door[lineDim] >= wall[lineDim] and door[2 + lineDim] <= wall[2 + lineDim] and abs(door[1 - lineDim] - wall[1 - lineDim]) <= self.wallWidth:
363
- values.append(door[lineDim])
364
- values.append(door[2 + lineDim])
365
- #doors.append(door)
366
- pass
367
- continue
368
-
369
- values.sort()
370
-
371
- fixedValue = (wall[1 - lineDim] + wall[3 - lineDim]) / 2
372
- for valueIndex, value in enumerate(values):
373
- if valueIndex % 2 == 0 and valueIndex > 0:
374
- v = EggVertex()
375
- if lineDim == 0:
376
- v.setPos(Point3D(1 - (value - deltas[0]), fixedValue - deltas[1], self.doorHeight))
377
- else:
378
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), value - deltas[1], self.doorHeight))
379
- pass
380
- v.setUv(Point2D(self.doorHeight / self.wallHeight, (value - wall[lineDim]) / (wall[2 + lineDim] - wall[lineDim])))
381
- poly.addVertex(vp.addVertex(v))
382
- pass
383
-
384
- v = EggVertex()
385
- if lineDim == 0:
386
- v.setPos(Point3D(1 - (value - deltas[0]), fixedValue - deltas[1], 0))
387
- else:
388
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), value - deltas[1], 0))
389
- pass
390
- v.setUv(Point2D(0, (value - wall[lineDim]) / (wall[2 + lineDim] - wall[lineDim])))
391
- poly.addVertex(vp.addVertex(v))
392
 
393
- if valueIndex % 2 == 1 and valueIndex + 1 < len(values):
394
- v = EggVertex()
395
- if lineDim == 0:
396
- v.setPos(Point3D(1 - (value - deltas[0]), fixedValue - deltas[1], self.doorHeight))
397
- else:
398
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), value - deltas[1], self.doorHeight))
399
- pass
400
- v.setUv(Point2D(self.doorHeight / self.wallHeight, (value - wall[lineDim]) / (wall[2 + lineDim] - wall[lineDim])))
401
- poly.addVertex(vp.addVertex(v))
402
- pass
403
- continue
404
- # v = EggVertex()
405
- # v.setPos(Point3D(wall[0] - deltas[0], wall[1] - deltas[1], 0))
406
- # v.setUv(Point2D(0, 0))
407
- # poly.addVertex(vp.addVertex(v))
408
-
409
- # v = EggVertex()
410
- # v.setPos(Point3D(wall[2] - deltas[0], wall[3] - deltas[1], 0))
411
- # v.setUv(Point2D(0, 1))
412
- # poly.addVertex(vp.addVertex(v))
413
-
414
- v = EggVertex()
415
- if lineDim == 0:
416
- v.setPos(Point3D(1 - (values[len(values) - 1] - deltas[0]), fixedValue - deltas[1], self.wallHeight))
417
- else:
418
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), values[len(values) - 1] - deltas[1], self.wallHeight))
419
- pass
420
- v.setUv(Point2D(1, 1))
421
- poly.addVertex(vp.addVertex(v))
422
-
423
- v = EggVertex()
424
- if lineDim == 0:
425
- v.setPos(Point3D(1 - (values[0] - deltas[0]), fixedValue - deltas[1], self.wallHeight))
426
- else:
427
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), values[0] - deltas[1], self.wallHeight))
428
- pass
429
- v.setUv(Point2D(1, 0))
430
- poly.addVertex(vp.addVertex(v))
431
-
432
- # for v in poly.getVertices():
433
- # print(v)
434
- # continue
435
-
436
- poly = EggPolygon()
437
- wallGroup.addChild(poly)
438
- if lineDim == 0:
439
- poly.setTexture(self.wallMats[wall[5]].getEggTexture())
440
- poly.setMaterial(self.wallMats[wall[5]].getEggMaterial())
441
- else:
442
- poly.setTexture(self.wallMats[wall[4]].getEggTexture())
443
- poly.setMaterial(self.wallMats[wall[4]].getEggMaterial())
444
- pass
445
-
446
- #deltas = (0.1, 0.1)
447
-
448
- for valueIndex, value in enumerate(values):
449
- if valueIndex % 2 == 0 and valueIndex > 0:
450
- v = EggVertex()
451
- if lineDim == 0:
452
- v.setPos(Point3D(1 - (value + deltas[0]), fixedValue + deltas[1], self.doorHeight))
453
- else:
454
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), value + deltas[1], self.doorHeight))
455
- pass
456
- v.setUv(Point2D(self.doorHeight / self.wallHeight, (value - wall[lineDim]) / (wall[2 + lineDim] - wall[lineDim])))
457
- poly.addVertex(vp.addVertex(v))
458
- pass
459
-
460
- v = EggVertex()
461
- if lineDim == 0:
462
- v.setPos(Point3D(1 - (value + deltas[0]), fixedValue + deltas[1], 0))
463
- else:
464
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), value + deltas[1], 0))
465
- pass
466
- v.setUv(Point2D(0, (value - wall[lineDim]) / (wall[2 + lineDim] - wall[lineDim])))
467
- poly.addVertex(vp.addVertex(v))
468
 
469
- if valueIndex % 2 == 1 and valueIndex + 1 < len(values):
470
- v = EggVertex()
471
- if lineDim == 0:
472
- v.setPos(Point3D(1 - (value + deltas[0]), fixedValue + deltas[1], self.doorHeight))
473
- else:
474
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), value + deltas[1], self.doorHeight))
475
- pass
476
- v.setUv(Point2D(self.doorHeight / self.wallHeight, (value - wall[lineDim]) / (wall[2 + lineDim] - wall[lineDim])))
477
- poly.addVertex(vp.addVertex(v))
478
- pass
479
- continue
480
- # v = EggVertex()
481
- # v.setPos(Point3D(wall[0] + deltas[0], wall[1] + deltas[1], 0))
482
- # v.setUv(Point2D(0, 0))
483
- # poly.addVertex(vp.addVertex(v))
484
-
485
- # v = EggVertex()
486
- # v.setPos(Point3D(wall[2] + deltas[0], wall[3] + deltas[1], 0))
487
- # v.setUv(Point2D(0, 1))
488
- # poly.addVertex(vp.addVertex(v))
489
-
490
- v = EggVertex()
491
- if lineDim == 0:
492
- v.setPos(Point3D(1 - (values[len(values) - 1] + deltas[0]), fixedValue + deltas[1], self.wallHeight))
493
- else:
494
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), values[len(values) - 1] + deltas[1], self.wallHeight))
495
- pass
496
- v.setUv(Point2D(1, 1))
497
- poly.addVertex(vp.addVertex(v))
498
-
499
- v = EggVertex()
500
- if lineDim == 0:
501
- v.setPos(Point3D(1 - (values[0] + deltas[0]), fixedValue + deltas[1], self.wallHeight))
502
- else:
503
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), values[0] + deltas[1], self.wallHeight))
504
- pass
505
- v.setUv(Point2D(1, 0))
506
- poly.addVertex(vp.addVertex(v))
507
-
508
-
509
-
510
-
511
- if lineDim == 0:
512
- poly = EggPolygon()
513
- wallGroup.addChild(poly)
514
- poly.setTexture(self.wallMats[10].getEggTexture())
515
- poly.setMaterial(self.wallMats[10].getEggMaterial())
516
-
517
- v = EggVertex()
518
- v.setPos(Point3D(1 - values[0], fixedValue - deltas[1], 0))
519
- v.setUv(Point2D(0, 0))
520
- poly.addVertex(vp.addVertex(v))
521
-
522
- v = EggVertex()
523
- v.setPos(Point3D(1 - values[0], fixedValue - deltas[1], self.wallHeight))
524
- v.setUv(Point2D(0, 1))
525
- poly.addVertex(vp.addVertex(v))
526
-
527
- v = EggVertex()
528
- v.setPos(Point3D(1 - values[0], fixedValue + deltas[1], self.wallHeight))
529
- v.setUv(Point2D(1, 1))
530
- poly.addVertex(vp.addVertex(v))
531
-
532
- v = EggVertex()
533
- v.setPos(Point3D(1 - values[0], fixedValue + deltas[1], 0))
534
- v.setUv(Point2D(1, 0))
535
- poly.addVertex(vp.addVertex(v))
536
-
537
-
538
- poly = EggPolygon()
539
- wallGroup.addChild(poly)
540
- poly.setTexture(self.wallMats[10].getEggTexture())
541
- poly.setMaterial(self.wallMats[10].getEggMaterial())
542
-
543
- v = EggVertex()
544
- v.setPos(Point3D(1 - values[0], fixedValue - deltas[1], self.wallHeight))
545
- v.setUv(Point2D(0, 0))
546
- poly.addVertex(vp.addVertex(v))
547
-
548
- v = EggVertex()
549
- v.setPos(Point3D(1 - values[len(values) - 1], fixedValue - deltas[1], self.wallHeight))
550
- v.setUv(Point2D(0, 1))
551
- poly.addVertex(vp.addVertex(v))
552
-
553
- v = EggVertex()
554
- v.setPos(Point3D(1 - values[len(values) - 1], fixedValue + deltas[1], self.wallHeight))
555
- v.setUv(Point2D(1, 1))
556
- poly.addVertex(vp.addVertex(v))
557
-
558
- v = EggVertex()
559
- v.setPos(Point3D(1 - values[0], fixedValue + deltas[1], self.wallHeight))
560
- v.setUv(Point2D(1, 0))
561
- poly.addVertex(vp.addVertex(v))
562
-
563
-
564
- poly = EggPolygon()
565
- wallGroup.addChild(poly)
566
- poly.setTexture(self.wallMats[10].getEggTexture())
567
- poly.setMaterial(self.wallMats[10].getEggMaterial())
568
-
569
- v = EggVertex()
570
- v.setPos(Point3D(1 - values[len(values) - 1], fixedValue - deltas[1], self.wallHeight))
571
- v.setUv(Point2D(0, 0))
572
- poly.addVertex(vp.addVertex(v))
573
-
574
- v = EggVertex()
575
- v.setPos(Point3D(1 - values[len(values) - 1], fixedValue - deltas[1], 0))
576
- v.setUv(Point2D(0, 1))
577
- poly.addVertex(vp.addVertex(v))
578
-
579
- v = EggVertex()
580
- v.setPos(Point3D(1 - values[len(values) - 1], fixedValue + deltas[1], 0))
581
- v.setUv(Point2D(1, 1))
582
- poly.addVertex(vp.addVertex(v))
583
-
584
- v = EggVertex()
585
- v.setPos(Point3D(1 - values[len(values) - 1], fixedValue + deltas[1], self.wallHeight))
586
- v.setUv(Point2D(1, 0))
587
- poly.addVertex(vp.addVertex(v))
588
 
589
- else:
590
- poly = EggPolygon()
591
- wallGroup.addChild(poly)
592
- poly.setTexture(self.wallMats[10].getEggTexture())
593
- poly.setMaterial(self.wallMats[10].getEggMaterial())
594
-
595
- v = EggVertex()
596
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), values[0], 0))
597
- v.setUv(Point2D(0, 0))
598
- poly.addVertex(vp.addVertex(v))
599
-
600
- v = EggVertex()
601
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), values[0], self.wallHeight))
602
- v.setUv(Point2D(0, 1))
603
- poly.addVertex(vp.addVertex(v))
604
-
605
- v = EggVertex()
606
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), values[0], self.wallHeight))
607
- v.setUv(Point2D(1, 1))
608
- poly.addVertex(vp.addVertex(v))
609
-
610
- v = EggVertex()
611
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), values[0], 0))
612
- v.setUv(Point2D(1, 0))
613
- poly.addVertex(vp.addVertex(v))
614
-
615
-
616
- poly = EggPolygon()
617
- wallGroup.addChild(poly)
618
- poly.setTexture(self.wallMats[10].getEggTexture())
619
- poly.setMaterial(self.wallMats[10].getEggMaterial())
620
-
621
- v = EggVertex()
622
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), values[0], self.wallHeight))
623
- v.setUv(Point2D(0, 0))
624
- poly.addVertex(vp.addVertex(v))
625
-
626
- v = EggVertex()
627
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), values[len(values) - 1], self.wallHeight))
628
- v.setUv(Point2D(0, 1))
629
- poly.addVertex(vp.addVertex(v))
630
-
631
- v = EggVertex()
632
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), values[len(values) - 1], self.wallHeight))
633
- v.setUv(Point2D(1, 1))
634
- poly.addVertex(vp.addVertex(v))
635
-
636
- v = EggVertex()
637
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), values[0], self.wallHeight))
638
- v.setUv(Point2D(1, 0))
639
- poly.addVertex(vp.addVertex(v))
640
-
641
-
642
- poly = EggPolygon()
643
- wallGroup.addChild(poly)
644
- poly.setTexture(self.wallMats[10].getEggTexture())
645
- poly.setMaterial(self.wallMats[10].getEggMaterial())
646
-
647
- v = EggVertex()
648
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), values[len(values) - 1], self.wallHeight))
649
- v.setUv(Point2D(0, 0))
650
- poly.addVertex(vp.addVertex(v))
651
-
652
- v = EggVertex()
653
- v.setPos(Point3D(1 - (fixedValue - deltas[0]), values[len(values) - 1], 0))
654
- v.setUv(Point2D(0, 1))
655
- poly.addVertex(vp.addVertex(v))
656
-
657
- v = EggVertex()
658
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), values[len(values) - 1], 0))
659
- v.setUv(Point2D(1, 1))
660
- poly.addVertex(vp.addVertex(v))
661
-
662
- v = EggVertex()
663
- v.setPos(Point3D(1 - (fixedValue + deltas[0]), values[len(values) - 1], self.wallHeight))
664
- v.setUv(Point2D(1, 0))
665
- poly.addVertex(vp.addVertex(v))
666
-
667
- continue
668
- return
669
-
670
-
671
- def generateDoors(self, data):
672
- doorsGroup = EggGroup('doors')
673
- data.addChild(doorsGroup)
674
-
675
- vp = EggVertexPool('door_vertex')
676
- doorsGroup.addChild(vp)
677
-
678
- for doorIndex, door in enumerate(self.doors):
679
- doorGroup = EggGroup('door_' + str(doorIndex))
680
- doorsGroup.addChild(doorGroup)
681
-
682
- lineDim = calcLineDim((door[:2], door[2:4]))
683
-
684
- if lineDim == 0:
685
- deltas = (0, self.doorWidth)
686
- else:
687
- deltas = (self.doorWidth, 0)
688
- pass
689
-
690
- poly = EggPolygon()
691
- doorGroup.addChild(poly)
692
- poly.setTexture(self.doorMat.getEggTexture())
693
- poly.setMaterial(self.doorMat.getEggMaterial())
694
-
695
- v = EggVertex()
696
- v.setPos(Point3D(1 - (door[0] - deltas[0]), door[1] - deltas[1], 0))
697
- v.setUv(Point2D(0, 0))
698
- poly.addVertex(vp.addVertex(v))
699
-
700
- v = EggVertex()
701
- v.setPos(Point3D(1 - (door[2] - deltas[0]), door[3] - deltas[1], 0))
702
- v.setUv(Point2D(1, 0))
703
- poly.addVertex(vp.addVertex(v))
704
-
705
- v = EggVertex()
706
- v.setPos(Point3D(1 - (door[2] - deltas[0]), door[3] - deltas[1], self.doorHeight))
707
- v.setUv(Point2D(1, 1))
708
- poly.addVertex(vp.addVertex(v))
709
-
710
- v = EggVertex()
711
- v.setPos(Point3D(1 - (door[0] - deltas[0]), door[1] - deltas[1], self.doorHeight))
712
- v.setUv(Point2D(0, 1))
713
- poly.addVertex(vp.addVertex(v))
714
-
715
-
716
- poly = EggPolygon()
717
- doorGroup.addChild(poly)
718
- poly.setTexture(self.doorMat.getEggTexture())
719
- poly.setMaterial(self.doorMat.getEggMaterial())
720
-
721
- v = EggVertex()
722
- v.setPos(Point3D(1 - (door[0] + deltas[0]), door[1] + deltas[1], 0))
723
- v.setUv(Point2D(0, 0))
724
- poly.addVertex(vp.addVertex(v))
725
-
726
- v = EggVertex()
727
- v.setPos(Point3D(1 - (door[2] + deltas[0]), door[3] + deltas[1], 0))
728
- v.setUv(Point2D(1, 0))
729
- poly.addVertex(vp.addVertex(v))
730
-
731
- v = EggVertex()
732
- v.setPos(Point3D(1 - (door[2] + deltas[0]), door[3] + deltas[1], self.doorHeight))
733
- v.setUv(Point2D(1, 1))
734
- poly.addVertex(vp.addVertex(v))
735
-
736
- v = EggVertex()
737
- v.setPos(Point3D(1 - (door[0] + deltas[0]), door[1] + deltas[1], self.doorHeight))
738
- v.setUv(Point2D(0, 1))
739
- poly.addVertex(vp.addVertex(v))
740
-
741
- continue
742
- return
743
-
744
-
745
- def generateWindows(self, data):
746
- windowsGroup = EggGroup('windows')
747
- data.addChild(windowsGroup)
748
-
749
- vp = EggVertexPool('window_vertex')
750
- windowsGroup.addChild(vp)
751
-
752
- for windowIndex, window in enumerate(self.windows):
753
- windowGroup = EggGroup('window_' + str(windowIndex))
754
- windowsGroup.addChild(windowGroup)
755
-
756
- lineDim = calcLineDim((window[:2], window[2:4]))
757
-
758
- if lineDim == 0:
759
- deltas = (0, self.windowWidth)
760
- else:
761
- deltas = (self.windowWidth, 0)
762
- pass
763
-
764
- poly = EggPolygon()
765
- windowGroup.addChild(poly)
766
- poly.setTexture(self.windowMat.getEggTexture())
767
- poly.setMaterial(self.windowMat.getEggMaterial())
768
-
769
- v = EggVertex()
770
- v.setPos(Point3D(1 - (window[0] - deltas[0]), window[1] - deltas[1], self.windowOffset))
771
- v.setUv(Point2D(0, 0))
772
- poly.addVertex(vp.addVertex(v))
773
-
774
- v = EggVertex()
775
- v.setPos(Point3D(1 - (window[2] - deltas[0]), window[3] - deltas[1], self.windowOffset))
776
- v.setUv(Point2D(1, 0))
777
- poly.addVertex(vp.addVertex(v))
778
-
779
- v = EggVertex()
780
- v.setPos(Point3D(1 - (window[2] - deltas[0]), window[3] - deltas[1], self.windowOffset + self.windowHeight))
781
- v.setUv(Point2D(1, 1))
782
- poly.addVertex(vp.addVertex(v))
783
-
784
- v = EggVertex()
785
- v.setPos(Point3D(1 - (window[0] - deltas[0]), window[1] - deltas[1], self.windowOffset + self.windowHeight))
786
- v.setUv(Point2D(0, 1))
787
- poly.addVertex(vp.addVertex(v))
788
-
789
-
790
- poly = EggPolygon()
791
- windowGroup.addChild(poly)
792
- poly.setTexture(self.windowMat.getEggTexture())
793
- poly.setMaterial(self.windowMat.getEggMaterial())
794
-
795
- v = EggVertex()
796
- v.setPos(Point3D(1 - (window[0] + deltas[0]), window[1] + deltas[1], self.windowOffset))
797
- v.setUv(Point2D(0, 0))
798
- poly.addVertex(vp.addVertex(v))
799
-
800
- v = EggVertex()
801
- v.setPos(Point3D(1 - (window[2] + deltas[0]), window[3] + deltas[1], self.windowOffset))
802
- v.setUv(Point2D(1, 0))
803
- poly.addVertex(vp.addVertex(v))
804
-
805
- v = EggVertex()
806
- v.setPos(Point3D(1 - (window[2] + deltas[0]), window[3] + deltas[1], self.windowOffset + self.windowHeight))
807
- v.setUv(Point2D(1, 1))
808
- poly.addVertex(vp.addVertex(v))
809
-
810
- v = EggVertex()
811
- v.setPos(Point3D(1 - (window[0] + deltas[0]), window[1] + deltas[1], self.windowOffset + self.windowHeight))
812
- v.setUv(Point2D(0, 1))
813
- poly.addVertex(vp.addVertex(v))
814
-
815
- continue
816
- return
817
-
818
-
819
- def generateIcons(self, scene):
820
- for icon in self.icons:
821
- if icon[4] not in self.iconNodes:
822
- continue
823
- #self.iconNodes[icon[4]].reparentTo(scene)
824
- node = deepcopy(self.iconNodes[icon[4]])
825
- node.setHpr(0, -90, 0)
826
- mins, maxs = node.getTightBounds()
827
- dimensions = Point3(maxs - mins)
828
-
829
- minDistances = [self.maxDim, self.maxDim, self.maxDim, self.maxDim]
830
- for wall in self.walls:
831
- lineDim = calcLineDim(((wall[0], wall[1]), (wall[2], wall[3])))
832
- if lineDim == -1:
833
- continue
834
- if ((icon[lineDim] + icon[2 + lineDim]) / 2 - wall[lineDim]) * ((icon[lineDim] + icon[2 + lineDim]) / 2 - wall[2 + lineDim]) > 0:
835
- continue
836
- side = int(wall[1 - lineDim] > (icon[1 - lineDim] + icon[3 - lineDim]) / 2)
837
- index = lineDim * 2 + side
838
- distance = abs(wall[1 - lineDim] - icon[1 - lineDim + side * 2])
839
- if distance < minDistances[index]:
840
- minDistances[index] = distance
841
- pass
842
- continue
843
-
844
-
845
- orientation = 0
846
- if icon[4] in ['cooking_counter']:
847
- if icon[2] - icon[0] > icon[3] - icon[1]:
848
- if minDistances[0] < minDistances[1]:
849
- orientation = 0
850
- else:
851
- orientation = 1
852
- else:
853
- if minDistances[2] < minDistances[3]:
854
- orientation = 2
855
- else:
856
- orientation = 3
857
- pass
858
- pass
859
- elif icon[4] in ['toilet']:
860
- if icon[2] - icon[0] < icon[3] - icon[1]:
861
- if minDistances[0] < minDistances[1]:
862
- orientation = 0
863
- else:
864
- orientation = 1
865
- else:
866
- if minDistances[2] < minDistances[3]:
867
- orientation = 2
868
- else:
869
- orientation = 3
870
- pass
871
- pass
872
- elif icon[4] in ['washing_basin']:
873
- orientation = np.argmin(minDistances)
874
- pass
875
-
876
 
877
- if orientation == 1:
878
- node.setH(180)
879
- elif orientation == 2:
880
- node.setH(90)
881
- elif orientation == 3:
882
- node.setH(270)
883
- pass
884
- if icon[4] == 'washing_basin':
885
- node.setH(90 + node.getH())
886
- mins, maxs = node.getTightBounds()
887
- dimensions = Point3(maxs - mins)
888
-
889
- # if ((maxs.getX() - mins.getX()) - (maxs.getY() - mins.getY())) * ((icon[2] - icon[0]) - (icon[3] - icon[1])) > 0:
890
- # scaleX = (icon[2] - icon[0]) / dimensions.getX()
891
- # scaleZ = (icon[3] - icon[1]) / dimensions.getZ()
892
- # scaleY = max(scaleX, scaleZ)
893
- # node.setScale(scaleX, scaleY, scaleZ)
894
- # node.setHpr(0, -90, 0)
895
- # node.setPos(icon[0] - mins.getX() * scaleX, icon[1] - mins.getZ() * scaleZ, maxs.getY() * scaleY)
896
- # orientation
897
- # else:
898
- # scaleX = (icon[3] - icon[1]) / dimensions.getX()
899
- # scaleZ = (icon[2] - icon[0]) / dimensions.getZ()
900
- # scaleY = max(scaleX, scaleZ)
901
- # node.setScale(scaleX, scaleY, scaleZ)
902
- # node.setHpr(90, -90, 0)
903
- # node.setPos(icon[0] + maxs.getZ() * scaleZ, icon[1] - mins.getX() * scaleX, maxs.getY() * scaleY)
904
- # #pivotNode = scene.attachNewNode("pivot")
905
- # #pivotNode.setPos(icon[0] - mins.getX() * scaleX, icon[1] - mins.getZ() * scaleZ, maxs.getY() * scaleY)
906
- # #node.wrtReparentTo(pivotNode)
907
- # #pivotNode.setHpr(90, 0, 0)
908
- # pass
909
-
910
-
911
- scaleX = (icon[2] - icon[0]) / dimensions.getX()
912
- scaleY = (icon[3] - icon[1]) / dimensions.getY()
913
- scaleZ = max(scaleX, scaleY)
914
- node.setScale(scaleX, scaleY, scaleZ)
915
- node.setPos(1 - icon[0] - maxs.getX() * scaleX, icon[1] - mins.getY() * scaleY, -mins.getZ() * scaleZ)
916
-
917
- node.setTwoSided(True)
918
- node.reparentTo(scene)
919
- #data.addChild(node.node())
920
- #node.setPos(icon[0], icon[1], 0)
921
- #node.reparentTo(data)
922
- continue
923
- return
924
-
925
- def generateEggModel(self):
926
- data = EggData()
927
- model = EggGroup('model')
928
- data.addChild(model)
929
- self.generateFloor(model)
930
- self.generateWalls(model)
931
- self.generateDoors(model)
932
- self.generateWindows(model)
933
- data.writeEgg(Filename("test/floorplan.egg"))
934
- scene = NodePath(loadEggData(data))
935
- self.generateIcons(scene)
936
- return scene
937
-
938
- poly = EggPolygon()
939
- data.addChild(poly)
940
-
941
-
942
- v = EggVertex()
943
- v.setPos(Point3D(0, 0, 0))
944
- v.setUv(Point2D(0, 0))
945
- poly.addVertex(vp.addVertex(v))
946
 
947
- v = EggVertex()
948
- v.setPos(Point3D(1, 0, 0))
949
- v.setUv(Point2D(1, 0))
950
- poly.addVertex(vp.addVertex(v))
951
-
952
- v = EggVertex()
953
- v.setPos(Point3D(1, 0, 1))
954
- v.setUv(Point2D(1, 1))
955
- poly.addVertex(vp.addVertex(v))
956
-
957
- v = EggVertex()
958
- v.setPos(Point3D(0, 0, 1))
959
- v.setUv(Point2D(0, 1))
960
- poly.addVertex(vp.addVertex(v))
961
-
962
- # To write the egg file to disk, use this:
963
- data.writeEgg(Filename("floorplan.egg"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
964
 
965
- # To load the egg file and render it immediately, use this:
966
- node = loadEggData(data)
967
- scene = NodePath(node)
968
- return scene
969
-
970
- def segmentRooms(self):
971
- wallMask = np.ones((self.height, self.width), np.uint8) * 255
972
- for wall in self.wallsInt:
973
- lineDim = calcLineDim(((wall[0], wall[1]), (wall[2], wall[3])))
974
- if lineDim == 0:
975
- wallMask[wall[1], wall[0]:wall[2] + 1] = 0
976
- else:
977
- wallMask[wall[1]:wall[3] + 1, wall[0]] = 0
978
- pass
979
- continue
980
- cv2.imwrite('test/walls.png', wallMask)
 
 
 
981
 
982
- numLabels, labels, stats, centroids = cv2.connectedComponentsWithStats(wallMask, 4)
983
- print(numLabels.shape)
984
- print(labels.shape)
985
- print(stats.shape)
986
- print(centroids.shape)
987
- cv2.imwrite('test/rooms.png', labels)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import numpy as np
2
  import cv2
3
  import copy
4
+
5
  def calcDistance(point_1, point_2):
6
+ return pow(pow(point_1[0] - point_2[0], 2) + pow(point_1[1] - point_2[1], 2), 0.5)
7
+
8
+ def calcLineDim(line, lineWidth=-1):
9
+ if abs(line[0][0] - line[1][0]) > abs(line[0][1] - line[1][1]):
10
+ if lineWidth < 0 or abs(line[0][1] - line[1][1]) <= lineWidth:
11
+ return 0
12
+ elif abs(line[0][0] - line[1][0]) < abs(line[0][1] - line[1][1]):
13
+ if lineWidth < 0 or abs(line[0][0] - line[1][0]) <= lineWidth:
14
+ return 1
15
+ else:
16
+ return -1
17
+
 
18
  class Floorplan():
19
+ def __init__(self, filename):
20
+ self.wallWidth = 0.005
21
+ self.filename = filename
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ # Remove 3D material and model references
24
+ self.wallMats = []
25
+ self.iconNodes = {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ def read(self):
28
+ floorplanFile = open(self.filename + '.txt', 'r')
29
+ self.walls = []
30
+ self.doors = []
31
+ self.icons = []
32
+ self.wallsInt = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ for line in floorplanFile.readlines():
35
+ line = line.strip()
36
+ values = line.split('\t')
37
+ if len(values) == 2:
38
+ self.width = float(values[0])
39
+ self.height = float(values[1])
40
+ self.maxDim = max(self.width, self.height)
41
+ elif len(values) == 6:
42
+ wall = []
43
+ for i in range(4):
44
+ wall.append(float(values[i]))
45
+
46
+ lineDim = calcLineDim(((wall[0], wall[1]), (wall[2], wall[3])))
47
+ wall[lineDim], wall[2 + lineDim] = min(wall[lineDim], wall[2 + lineDim]), max(wall[lineDim], wall[2 + lineDim])
48
+ wall[1 - lineDim] = wall[3 - lineDim] = (wall[1 - lineDim] + wall[3 - lineDim]) / 2
49
+ wall.append(int(values[4]) - 1)
50
+ wall.append(int(values[5]) - 1)
51
+
52
+ for pointIndex in range(2):
53
+ wall[pointIndex * 2 + 0] /= self.maxDim
54
+ wall[pointIndex * 2 + 1] /= self.maxDim
55
+
56
+ self.walls.append(wall)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
+ wallInt = []
59
+ for i in range(4):
60
+ wallInt.append(int(values[i]))
61
+
62
+ wallInt[lineDim], wallInt[2 + lineDim] = min(wallInt[lineDim], wallInt[2 + lineDim]), max(wallInt[lineDim], wallInt[2 + lineDim])
63
+ self.wallsInt.append(wallInt)
64
+
65
+ elif len(values) == 7:
66
+ item = []
67
+ for i in range(4):
68
+ item.append(float(values[i]))
69
+
70
+ for pointIndex in range(2):
71
+ item[pointIndex * 2 + 0] /= self.maxDim
72
+ item[pointIndex * 2 + 1] /= self.maxDim
73
+
74
+ if values[4] == 'door':
75
+ self.doors.append(item)
76
+ else:
77
+ item.append(values[4])
78
+ self.icons.append(item)
79
+
80
+ return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
+ def processFloorplan(self):
83
+ # Process exterior walls
84
+ exteriorWalls = []
85
+ for wall in self.walls:
86
+ if wall[4] == 10 or wall[5] == 10:
87
+ exteriorWalls.append(copy.deepcopy(wall))
88
+
89
+ # Process exterior openings (doors/windows)
90
+ exteriorOpenings = []
91
+ for wall in exteriorWalls:
92
+ lineDim = calcLineDim((wall[:2], wall[2:4]))
93
+ for doorIndex, door in enumerate(self.doors):
94
+ if calcLineDim((door[:2], door[2:4])) != lineDim:
95
+ continue
96
+ if (door[lineDim] >= wall[lineDim] and
97
+ door[2 + lineDim] <= wall[2 + lineDim] and
98
+ abs(door[1 - lineDim] - wall[1 - lineDim]) <= self.wallWidth):
99
+ exteriorOpenings.append(doorIndex)
100
+
101
+ # Find main entrance door
102
+ minDistance = 10000
103
+ mainDoorIndex = -1
104
+ for icon in self.icons:
105
+ if icon[4] == 'entrance':
106
+ for doorIndex in exteriorOpenings:
107
+ door = self.doors[doorIndex]
108
+ distance = pow(pow((door[0] + door[2]) / 2 - (icon[0] + icon[2]) / 2, 2) +
109
+ pow((door[1] + door[3]) / 2 - (icon[1] + icon[3]) / 2, 2), 0.5)
110
+ if distance < minDistance:
111
+ minDistance = distance
112
+ mainDoorIndex = doorIndex
113
+ break
114
+
115
+ # Separate doors and windows
116
+ newDoors = []
117
+ self.windows = []
118
+ for doorIndex, door in enumerate(self.doors):
119
+ if doorIndex == mainDoorIndex or doorIndex not in exteriorOpenings:
120
+ newDoors.append(door)
121
+ else:
122
+ self.windows.append(door)
123
+ self.doors = newDoors
124
+
125
+ # Find exterior wall loops
126
+ exteriorWallLoops = []
127
+ visitedMask = {}
128
+ gap = 5.0 / self.maxDim
129
+
130
+ for wallIndex, wall in enumerate(exteriorWalls):
131
+ if wallIndex in visitedMask:
132
+ continue
133
+
134
+ visitedMask[wallIndex] = True
135
+ exteriorWallLoop = []
136
+ exteriorWallLoop.append(wall)
137
+
138
+ for loopWall in exteriorWallLoop:
139
+ for neighborWallIndex, neighborWall in enumerate(exteriorWalls):
140
+ if neighborWallIndex in visitedMask:
141
+ continue
142
+
143
+ if calcDistance(neighborWall[:2], loopWall[2:4]) < gap:
144
+ exteriorWallLoop.append(neighborWall)
145
+ visitedMask[neighborWallIndex] = True
146
+ break
147
+ elif calcDistance(neighborWall[2:4], loopWall[2:4]) < gap:
148
+ neighborWall[0], neighborWall[2] = neighborWall[2], neighborWall[0]
149
+ neighborWall[1], neighborWall[3] = neighborWall[3], neighborWall[1]
150
+ exteriorWallLoop.append(neighborWall)
151
+ visitedMask[neighborWallIndex] = True
152
+ break
153
+
154
+ exteriorWallLoops.append(exteriorWallLoop)
155
+
156
+ return exteriorWallLoops
157
 
158
+ def segmentRooms(self):
159
+ wallMask = np.ones((int(self.height), int(self.width)), np.uint8) * 255
160
+ for wall in self.wallsInt:
161
+ lineDim = calcLineDim(((wall[0], wall[1]), (wall[2], wall[3])))
162
+ if lineDim == 0:
163
+ wallMask[wall[1], wall[0]:wall[2] + 1] = 0
164
+ else:
165
+ wallMask[wall[1]:wall[3] + 1, wall[0]] = 0
166
+
167
+ cv2.imwrite('test/walls.png', wallMask)
168
+
169
+ numLabels, labels, stats, centroids = cv2.connectedComponentsWithStats(wallMask, 4)
170
+ print("Number of labels:", numLabels)
171
+ print("Labels shape:", labels.shape)
172
+ print("Stats shape:", stats.shape)
173
+ print("Centroids shape:", centroids.shape)
174
+
175
+ cv2.imwrite('test/rooms.png', labels)
176
+ return labels
177
 
178
+ def generateFloorplanImage(self):
179
+ # Create a blank image
180
+ img = np.ones((int(self.height), int(self.width), 3), dtype=np.uint8) * 255
181
+
182
+ # Draw walls
183
+ for wall in self.wallsInt:
184
+ cv2.line(img, (wall[0], wall[1]), (wall[2], wall[3]), (0, 0, 0), 2)
185
+
186
+ # Draw doors
187
+ for door in self.doors:
188
+ door_int = [int(x * self.maxDim) for x in door[:4]]
189
+ cv2.line(img, (door_int[0], door_int[1]), (door_int[2], door_int[3]), (0, 255, 0), 2)
190
+
191
+ # Draw windows
192
+ for window in self.windows:
193
+ window_int = [int(x * self.maxDim) for x in window[:4]]
194
+ cv2.line(img, (window_int[0], window_int[1]), (window_int[2], window_int[3]), (0, 0, 255), 2)
195
+
196
+ # Draw icons
197
+ for icon in self.icons:
198
+ icon_int = [int(x * self.maxDim) for x in icon[:4]]
199
+ cv2.rectangle(img, (icon_int[0], icon_int[1]), (icon_int[2], icon_int[3]), (255, 0, 0), 2)
200
+ if len(icon) > 4:
201
+ cv2.putText(img, icon[4], (icon_int[0], icon_int[1]),
202
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
203
+
204
+ return img