Class: Topolys::Shell

Inherits:
Object
  • Object
show all
Defined in:
lib/topolys/model.rb

Overview

Face

Instance Attribute Summary collapse

Attributes inherited from Object

#attributes, #children, #id, #parents

Instance Method Summary collapse

Methods inherited from Object

#debug, #hash, link, #link_child, #link_parent, #short_id, #short_name, #to_s, unlink, #unlink_child, #unlink_parent

Constructor Details

#initialize(faces) ⇒ Shell

Initializes a Shell object

Throws if faces are not connected

Parameters:

  • faces (Array)

    Array of Face



1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
# File 'lib/topolys/model.rb', line 1313

def initialize(faces)
  super()
  @faces = faces
  @all_edges = []
  @shared_edges = []
  @edge_to_face_map = {}
  @connection_matrix = Matrix.identity(faces.size)

  recalculate
end

Instance Attribute Details

#all_edgesArray (readonly)

Returns Array of all edges from outer faces.

Returns:

  • (Array)

    Array of all edges from outer faces



1296
1297
1298
# File 'lib/topolys/model.rb', line 1296

def all_edges
  @all_edges
end

#connection_matrixMatrix (readonly)

Returns Matrix of level 1 face to face connections.

Returns:

  • (Matrix)

    Matrix of level 1 face to face connections



1305
1306
1307
# File 'lib/topolys/model.rb', line 1305

def connection_matrix
  @connection_matrix
end

#edge_to_face_mapHash (readonly)

Returns Map edges to array of outer faces.

Returns:

  • (Hash)

    Map edges to array of outer faces



1302
1303
1304
# File 'lib/topolys/model.rb', line 1302

def edge_to_face_map
  @edge_to_face_map
end

#shared_edgesArray (readonly)

Returns Array of shared edges from outer faces.

Returns:

  • (Array)

    Array of shared edges from outer faces



1299
1300
1301
# File 'lib/topolys/model.rb', line 1299

def shared_edges
  @shared_edges
end

Instance Method Details

#child_classObject



1415
1416
1417
# File 'lib/topolys/model.rb', line 1415

def child_class
  Face
end

#closed?Bool

Checks if faces form a closed Shell

Returns:

  • (Bool)

    Returns true if closed



1403
1404
1405
1406
1407
1408
1409
# File 'lib/topolys/model.rb', line 1403

def closed?
  @edge_to_face_map.each_value do |faces|
    return false if faces.size != 2
  end

  return @all_edges == @shared_edges
end

#facesObject



1419
1420
1421
# File 'lib/topolys/model.rb', line 1419

def faces
  @children
end

#normalize_connection_matrix(m) ⇒ Object



1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
# File 'lib/topolys/model.rb', line 1388

def normalize_connection_matrix(m)
  n = faces.size
  result = Matrix.identity(n)
  (0...n).each do |i|
    (i+1...n).each do |j|
      result[i,j] = result[j,i] = (m[i,j] > 0 ? 1 : 0)
    end
  end
  return result
end

#parent_classObject



1411
1412
1413
# File 'lib/topolys/model.rb', line 1411

def parent_class
  NilClass
end

#recalculateObject



1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
# File 'lib/topolys/model.rb', line 1330

def recalculate

  # unlink from any previous faces
  @children.reverse_each {|child| Object.unlink(self, child)}

  # link with current faces
  @faces.each {|face| Object.link(self, face)}

  # recompute cached properties and check invariants
  n = @faces.size

  # can't have duplicate faces
  face_ids = @faces.map{|face| face.id}.uniq.sort
  raise "Duplicate faces in shell" if face_ids.size != n

  @all_edges = []
  @shared_edges = []
  @edge_to_face_map = {}
  @connection_matrix = Matrix.identity(faces.size)
  (0...n).each do |i|

    # populate edge_to_face_map and all_edges
    @faces[i].outer.edges.each do |edge|
      @edge_to_face_map[edge.id] = [] if @edge_to_face_map[edge.id].nil?
      @edge_to_face_map[edge.id] << @faces[i]
      @all_edges << edge
    end

    # loop over other edges
    (i+1...n).each do |j|
      shared_edges = @faces[i].shared_outer_edges(@faces[j])
      #puts "#{i}, #{j}, [#{shared_edges.map{|e| e.short_name}.join(', ')}]"
      @shared_edges.concat(shared_edges)
      if !shared_edges.empty?
        @connection_matrix[i,j] = @connection_matrix[j,i] = 1
      end
    end
  end
  @shared_edges.uniq! {|e| e.id}
  @shared_edges.sort_by! {|e| e.id}
  @all_edges.uniq! {|e| e.id}
  @all_edges.sort_by! {|e| e.id}

  temp_last = @connection_matrix
  temp = normalize_connection_matrix(temp_last * @connection_matrix)
  i = 0
  while temp_last != temp
    temp_last = temp
    temp = normalize_connection_matrix(temp * @connection_matrix)
    i += 1
    break if i > 100
  end

  # check that every face is connected to every other faces
  temp.each {|connection| raise "Faces not connected in shell" if connection == 0}

end

#to_jsonObject



1324
1325
1326
1327
1328
# File 'lib/topolys/model.rb', line 1324

def to_json
  result = super
  result[:faces] = @faces.map { |h| h.id }
  return result
end