mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Fetch latest commits
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from distutils.command.sdist import sdist
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.pset
|
||||
|
||||
|
||||
@@ -32,7 +32,20 @@ class Usecase:
|
||||
self.calendar_cache = {}
|
||||
self.cascade_task(self.settings["task"], is_first_task=True)
|
||||
|
||||
def cascade_task(self, task, is_first_task=False):
|
||||
def cascade_task(self, task, is_first_task=False, task_sequence=None):
|
||||
if task_sequence is None:
|
||||
task_sequence = []
|
||||
|
||||
if task in task_sequence:
|
||||
print("Warning! Recursive sequence is as follows:")
|
||||
for i, debug_task in enumerate(task_sequence):
|
||||
if i == 0:
|
||||
print("Starting at", debug_task)
|
||||
else:
|
||||
print("... is a predecessor to ...", debug_task)
|
||||
print("... which is cyclically a predecessor to ...", task)
|
||||
raise Exception("Recursive tasks found. Could not cascade schedule.")
|
||||
|
||||
if not task.TaskTime:
|
||||
return
|
||||
|
||||
@@ -170,7 +183,7 @@ class Usecase:
|
||||
)
|
||||
|
||||
for rel in task.IsPredecessorTo:
|
||||
self.cascade_task(rel.RelatedProcess)
|
||||
self.cascade_task(rel.RelatedProcess, task_sequence=task_sequence + [task])
|
||||
|
||||
def get_lag_time_days(self, lag_time):
|
||||
return ifcopenshell.util.date.ifc2datetime(lag_time.LagValue.wrappedValue).days
|
||||
|
||||
@@ -39,14 +39,32 @@ class Usecase:
|
||||
if not self.start_dates:
|
||||
return
|
||||
|
||||
is_cyclic = False
|
||||
attempts = 0
|
||||
self.pending_nodes = set(self.g.nodes)
|
||||
max_worst_case_attempts = pow(len(self.pending_nodes), 2)
|
||||
while self.pending_nodes:
|
||||
attempts += 1
|
||||
remaining_nodes = set()
|
||||
for pending_node in self.pending_nodes:
|
||||
if not self.forward_pass(pending_node):
|
||||
remaining_nodes.add(pending_node)
|
||||
self.pending_nodes = remaining_nodes
|
||||
|
||||
# As we parse nodes, the remaining attempts can drop dramatically, so we recalculate the upper limit
|
||||
max_remaining_attempts = pow(len(self.pending_nodes), 2)
|
||||
if max_remaining_attempts < max_worst_case_attempts:
|
||||
max_worst_case_attempts = max_remaining_attempts
|
||||
attempts = 0
|
||||
|
||||
if attempts > max_worst_case_attempts:
|
||||
is_cyclic = True
|
||||
break # We have an infinite loop due to a cyclic graph
|
||||
|
||||
if is_cyclic:
|
||||
raise Exception("Task graph is cyclic and so critical path method cannot be performed.")
|
||||
return
|
||||
|
||||
self.pending_nodes = set(self.g.nodes)
|
||||
while self.pending_nodes:
|
||||
remaining_nodes = set()
|
||||
|
||||
@@ -27,7 +27,6 @@ class Selector:
|
||||
def parse(cls, ifc_file, query, elements=None):
|
||||
cls.file = ifc_file
|
||||
cls.elements = elements
|
||||
|
||||
l = lark.Lark(
|
||||
"""start: query (lfunction query)*
|
||||
query: selector | group
|
||||
@@ -38,7 +37,7 @@ class Selector:
|
||||
filter: "[" filter_key (comparison filter_value)? "]"
|
||||
filter_key: WORD | pset_or_qto
|
||||
filter_value: ESCAPED_STRING | SIGNED_FLOAT | SIGNED_INT | BOOLEAN | NULL
|
||||
pset_or_qto: /[A-Za-z0-9_]+/ "." /[A-Za-z0-9_]+/
|
||||
pset_or_qto: /[^\W][^.=<>]*[^\W]/ "." /[^\W][^.=<>]*[^\W]/
|
||||
lfunction: and | or
|
||||
inverse_relationship: types | decomposed_by | bounded_by
|
||||
types: "*"
|
||||
@@ -185,7 +184,7 @@ class Selector:
|
||||
elif token_type == "SIGNED_FLOAT":
|
||||
value = float(filter_rule.children[2].children[0])
|
||||
elif token_type == "BOOLEAN":
|
||||
value = filter_rule.children[2].children[0].lower() == 'true'
|
||||
value = filter_rule.children[2].children[0].lower() == "true"
|
||||
elif token_type == "NULL":
|
||||
value = None
|
||||
for element in elements:
|
||||
|
||||
Reference in New Issue
Block a user