irie 0.0.58__py3-none-any.whl → 0.0.60__py3-none-any.whl
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.
Potentially problematic release.
This version of irie might be problematic. Click here for more details.
- irie/apps/evaluation/models.py +7 -0
- irie/apps/events/views_events.py +2 -2
- irie/apps/inventory/migrations/0009_datum_angle_x_datum_angle_y.py +23 -0
- irie/apps/inventory/models.py +1 -1
- irie/apps/inventory/views.py +10 -4
- irie/apps/prediction/forms/csi_upload.py +68 -0
- irie/apps/prediction/migrations/0007_remove_sensorassignment_orient_x_and_more.py +25 -0
- irie/apps/prediction/runners/__init__.py +6 -4
- irie/apps/prediction/runners/opensees/__init__.py +49 -14
- irie/apps/prediction/urls.py +6 -4
- irie/apps/prediction/views.py +248 -17
- irie/apps/static/assets/css/brace.css +1 -1
- irie/apps/static/assets/css/brace.css.map +1 -1
- irie/apps/static/assets/css/brace.min.css +1 -1
- irie/apps/static/assets/js/brace.js +101 -42
- irie/apps/templates/includes/footer.html +1 -1
- irie/apps/templates/inventory/asset-event-summary.html +7 -0
- irie/apps/templates/inventory/asset-on-map.html +22 -22
- irie/apps/templates/inventory/asset-on-map.js +115 -113
- irie/apps/templates/inventory/create-datum.html +44 -0
- irie/apps/templates/inventory/sensor-upload.html +22 -22
- irie/apps/templates/layouts/base.html +3 -3
- irie/apps/templates/prediction/create-model.html +32 -37
- irie/apps/templates/prediction/upload/confirm.html +93 -0
- irie/apps/templates/prediction/upload/step.html +119 -0
- irie/apps/templates/prediction/veux/navigator.html +54 -38
- irie/apps/templates/prediction/veux/navigator.js +222 -154
- irie/apps/templates/prediction/xara-profile.html +7 -3
- irie/core/settings.py +1 -0
- {irie-0.0.58.dist-info → irie-0.0.60.dist-info}/METADATA +7 -6
- {irie-0.0.58.dist-info → irie-0.0.60.dist-info}/RECORD +35 -29
- /irie/apps/prediction/{forms.py → forms/__init__.py} +0 -0
- {irie-0.0.58.dist-info → irie-0.0.60.dist-info}/WHEEL +0 -0
- {irie-0.0.58.dist-info → irie-0.0.60.dist-info}/entry_points.txt +0 -0
- {irie-0.0.58.dist-info → irie-0.0.60.dist-info}/top_level.txt +0 -0
irie/apps/prediction/views.py
CHANGED
|
@@ -16,13 +16,15 @@ import uuid
|
|
|
16
16
|
import base64
|
|
17
17
|
import hashlib
|
|
18
18
|
|
|
19
|
+
from django.template.loader import render_to_string
|
|
20
|
+
from django.utils.html import escape
|
|
19
21
|
from django.template import loader
|
|
20
22
|
from django.contrib.auth.decorators import login_required
|
|
21
23
|
from django.core.exceptions import ObjectDoesNotExist
|
|
22
24
|
from django.core.files.base import ContentFile
|
|
23
25
|
from django.shortcuts import HttpResponse, get_object_or_404
|
|
24
26
|
|
|
25
|
-
from irie.apps.inventory.models import Asset
|
|
27
|
+
from irie.apps.inventory.models import Asset, Datum
|
|
26
28
|
from irie.apps.prediction.predictor import PREDICTOR_TYPES
|
|
27
29
|
from irie.apps.prediction.models import PredictorModel
|
|
28
30
|
from .forms import PredictorForm
|
|
@@ -76,25 +78,93 @@ def asset_predictors(request, calid):
|
|
|
76
78
|
def predictor_render(request, calid, preid):
|
|
77
79
|
|
|
78
80
|
predictor = get_object_or_404(PredictorModel, pk=int(preid))
|
|
81
|
+
|
|
82
|
+
canvas = None
|
|
83
|
+
|
|
84
|
+
sname = request.GET.get("section", None)
|
|
85
|
+
|
|
86
|
+
runner = predictor.runner
|
|
87
|
+
|
|
88
|
+
if sname is None:
|
|
89
|
+
try:
|
|
90
|
+
artist = runner.render()
|
|
91
|
+
if artist is None:
|
|
92
|
+
return HttpResponse(
|
|
93
|
+
json.dumps({"error": "No rendering available"}),
|
|
94
|
+
content_type="application/json",
|
|
95
|
+
status=404
|
|
96
|
+
)
|
|
97
|
+
canvas = artist.canvas
|
|
98
|
+
except Exception as e:
|
|
99
|
+
return HttpResponse(
|
|
100
|
+
json.dumps({"error": str(e)}),
|
|
101
|
+
content_type="application/json",
|
|
102
|
+
status=500
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
try:
|
|
106
|
+
_, mesh = runner.structural_section(sname)
|
|
107
|
+
|
|
108
|
+
artist = veux.create_artist(mesh.model, canvas="gltf")
|
|
109
|
+
artist.draw_surfaces()
|
|
110
|
+
# artist.draw_outlines()
|
|
111
|
+
canvas = artist.canvas
|
|
112
|
+
# canvas = veux._create_canvas(name="gltf")
|
|
113
|
+
import numpy as np
|
|
114
|
+
R = np.array([[1, 0],
|
|
115
|
+
[0, 1],
|
|
116
|
+
[0, 0]])
|
|
117
|
+
exterior = mesh.exterior()
|
|
118
|
+
exterior = np.append(exterior, np.array([[exterior[0][0], exterior[0][1]]]), axis=0)
|
|
119
|
+
|
|
120
|
+
canvas.plot_lines(exterior@R.T)
|
|
121
|
+
if (interior := mesh.interior()) is not None:
|
|
122
|
+
for i in interior:
|
|
123
|
+
i = np.append(i, np.array([[i[0][0], i[0][1]]]), axis=0)
|
|
124
|
+
canvas.plot_lines(i@R.T)
|
|
125
|
+
try:
|
|
126
|
+
canvas.plot_vectors(np.zeros((3,3)),
|
|
127
|
+
np.eye(3)*min(mesh.depth, mesh.width)/3, extrude=True)
|
|
128
|
+
except:
|
|
129
|
+
pass
|
|
130
|
+
|
|
131
|
+
except Exception as e:
|
|
132
|
+
raise e
|
|
133
|
+
return HttpResponse(
|
|
134
|
+
json.dumps({"error": "Section not found"}),
|
|
135
|
+
content_type="application/json",
|
|
136
|
+
status=404
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
if canvas is None:
|
|
140
|
+
return HttpResponse(
|
|
141
|
+
json.dumps({"error": "No rendering available"}),
|
|
142
|
+
content_type="application/json",
|
|
143
|
+
status=404
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
glb = canvas.to_glb()
|
|
147
|
+
return HttpResponse(glb, content_type="application/binary")
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@login_required(login_url="/login/")
|
|
151
|
+
def predictor_table(request, calid, preid):
|
|
152
|
+
|
|
153
|
+
predictor = get_object_or_404(PredictorModel, pk=int(preid))
|
|
79
154
|
|
|
80
155
|
sname = request.GET.get("section", None)
|
|
81
156
|
|
|
82
|
-
runner =
|
|
157
|
+
runner = predictor.runner
|
|
83
158
|
|
|
84
159
|
try:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
can.plot_lines(mesh.exterior()@R.T)
|
|
91
|
-
if (interior := mesh.interior()) is not None:
|
|
92
|
-
for i in interior:
|
|
93
|
-
can.plot_lines(i@R.T)
|
|
94
|
-
glb = can.to_glb()
|
|
95
|
-
return HttpResponse(glb, content_type="application/binary")
|
|
160
|
+
properties, _ = runner.structural_section(sname)
|
|
161
|
+
|
|
162
|
+
data = json.dumps(properties)
|
|
163
|
+
return HttpResponse(data,
|
|
164
|
+
content_type="application/json")
|
|
96
165
|
|
|
97
166
|
except Exception as e:
|
|
167
|
+
print(e)
|
|
98
168
|
return HttpResponse(
|
|
99
169
|
json.dumps({"error": "Section not found"}),
|
|
100
170
|
content_type="application/json",
|
|
@@ -102,6 +172,44 @@ def predictor_render(request, calid, preid):
|
|
|
102
172
|
)
|
|
103
173
|
|
|
104
174
|
|
|
175
|
+
@login_required(login_url="/login/")
|
|
176
|
+
def predictor_analysis(request, calid, preid):
|
|
177
|
+
|
|
178
|
+
predictor = get_object_or_404(PredictorModel, pk=int(preid))
|
|
179
|
+
|
|
180
|
+
runner = predictor.runner
|
|
181
|
+
sname = request.GET.get("section", None)
|
|
182
|
+
|
|
183
|
+
if sname is not None:
|
|
184
|
+
|
|
185
|
+
try:
|
|
186
|
+
_, mesh = runner.structural_section(sname)
|
|
187
|
+
except Exception as e:
|
|
188
|
+
return HttpResponse(
|
|
189
|
+
json.dumps({"error": "Section not found"}),
|
|
190
|
+
content_type="application/json",
|
|
191
|
+
status=404
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
try:
|
|
195
|
+
content = "<div></div>"
|
|
196
|
+
return HttpResponse(content)
|
|
197
|
+
|
|
198
|
+
except Exception as e:
|
|
199
|
+
return HttpResponse(
|
|
200
|
+
json.dumps({"error": str(e)}),
|
|
201
|
+
content_type="application/json",
|
|
202
|
+
status=500
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
return HttpResponse(
|
|
207
|
+
json.dumps({"error": str(e)}),
|
|
208
|
+
content_type="application/json",
|
|
209
|
+
status=500
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
|
|
105
213
|
@login_required(login_url="/login/")
|
|
106
214
|
def predictor_profile(request, calid, preid):
|
|
107
215
|
|
|
@@ -124,8 +232,8 @@ def predictor_profile(request, calid, preid):
|
|
|
124
232
|
|
|
125
233
|
predictor = get_object_or_404(PredictorModel, pk=int(preid))
|
|
126
234
|
|
|
127
|
-
context["asset"]
|
|
128
|
-
context["runner"]
|
|
235
|
+
context["asset"] = asset
|
|
236
|
+
context["runner"] = predictor.runner
|
|
129
237
|
context["predictor"] = predictor
|
|
130
238
|
context["sensors"] = predictor.sensorassignment_set.all()
|
|
131
239
|
|
|
@@ -151,7 +259,8 @@ def predictor_profile(request, calid, preid):
|
|
|
151
259
|
if "DEBUG" in os.environ and os.environ["DEBUG"]:
|
|
152
260
|
raise e
|
|
153
261
|
html_template = loader.get_template("site/page-500.html")
|
|
154
|
-
return HttpResponse(html_template.render(context, request))
|
|
262
|
+
return HttpResponse(html_template.render(context, request), status=500)
|
|
263
|
+
|
|
155
264
|
|
|
156
265
|
|
|
157
266
|
@login_required(login_url="/login/")
|
|
@@ -204,7 +313,6 @@ def asset_map(request, calid):
|
|
|
204
313
|
return HttpResponse(r200.render(context, request))
|
|
205
314
|
|
|
206
315
|
except Exception as e:
|
|
207
|
-
raise e
|
|
208
316
|
r500 = loader.get_template("site/page-500.html")
|
|
209
317
|
return HttpResponse(r500.render({"message": str(e)}, request), status=500)
|
|
210
318
|
|
|
@@ -220,7 +328,129 @@ def create_mdof(request):
|
|
|
220
328
|
html_template = loader.get_template("prediction/" + page_template)
|
|
221
329
|
return HttpResponse(html_template.render(context, request))
|
|
222
330
|
|
|
331
|
+
from formtools.wizard.views import SessionWizardView
|
|
332
|
+
from .forms.csi_upload import DatumCreateForm, DatumSelectForm, PredictorForm, SensorForm, ConfirmForm
|
|
333
|
+
|
|
334
|
+
FORMS = [
|
|
335
|
+
("select datum", DatumSelectForm),
|
|
336
|
+
("create datum", DatumCreateForm),
|
|
337
|
+
("structure", PredictorForm),
|
|
338
|
+
("sensor", SensorForm),
|
|
339
|
+
("confirm", ConfirmForm),
|
|
340
|
+
]
|
|
341
|
+
|
|
342
|
+
TEMPLATES = {
|
|
343
|
+
"select datum": "prediction/upload/step.html",
|
|
344
|
+
"create datum": "prediction/upload/step.html",
|
|
345
|
+
"structure": "prediction/upload/step.html",
|
|
346
|
+
"sensor": "prediction/upload/step.html",
|
|
347
|
+
"confirm": "prediction/upload/step.html",
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
from django.shortcuts import redirect
|
|
351
|
+
from django.core.files.storage import FileSystemStorage
|
|
352
|
+
from django.conf import settings
|
|
353
|
+
|
|
354
|
+
class CsiUpload(SessionWizardView):
|
|
355
|
+
form_list = FORMS
|
|
356
|
+
file_storage = FileSystemStorage(location=settings.MEDIA_ROOT)
|
|
357
|
+
|
|
358
|
+
condition_dict = {
|
|
359
|
+
"create datum": lambda self: (
|
|
360
|
+
self.get_cleaned_data_for_step("select datum") is None \
|
|
361
|
+
or self.get_cleaned_data_for_step("select datum").get("datum") is None
|
|
362
|
+
),
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
def dispatch(self, request, *args, **kwargs):
|
|
366
|
+
self.asset = get_object_or_404(Asset, calid=kwargs["calid"])
|
|
367
|
+
self.request = request
|
|
368
|
+
return super().dispatch(request, *args, **kwargs)
|
|
369
|
+
|
|
370
|
+
def get_template_names(self):
|
|
371
|
+
return [TEMPLATES[self.steps.current]]
|
|
372
|
+
|
|
373
|
+
def get_form_kwargs(self, step=None):
|
|
374
|
+
kwargs = super().get_form_kwargs(step)
|
|
375
|
+
|
|
376
|
+
if step == "select datum":
|
|
377
|
+
kwargs["asset"] = self.asset
|
|
378
|
+
kwargs["initial"] = {"asset": self.asset.id}
|
|
379
|
+
kwargs["datum_queryset"] = Datum.objects.filter(asset=self.asset)
|
|
380
|
+
elif step == "create datum":
|
|
381
|
+
kwargs["asset"] = self.asset
|
|
382
|
+
kwargs["initial"] = {"asset": self.asset.id}
|
|
383
|
+
elif step == "structure":
|
|
384
|
+
kwargs["asset"] = self.asset
|
|
385
|
+
kwargs["initial"] = {
|
|
386
|
+
"asset": self.asset,
|
|
387
|
+
"active": False,
|
|
388
|
+
"protocol": PredictorModel.Protocol.TYPE1,
|
|
389
|
+
}
|
|
390
|
+
elif step == "sensor":
|
|
391
|
+
datum_data = self.get_cleaned_data_for_step("datum") or {}
|
|
392
|
+
kwargs["initial"] = {
|
|
393
|
+
# "datum": datum_data.get("id"),
|
|
394
|
+
"asset": self.asset.id,
|
|
395
|
+
"node": -1,
|
|
396
|
+
"predictor": self.get_cleaned_data_for_step("structure").get("id")
|
|
397
|
+
}
|
|
398
|
+
return kwargs
|
|
399
|
+
|
|
400
|
+
def get_context_data(self, form, **kwargs):
|
|
401
|
+
context = super().get_context_data(form=form, **kwargs)
|
|
402
|
+
context["asset"] = self.asset
|
|
403
|
+
context["segment"] = "assets"
|
|
404
|
+
context["step"] = self.steps.current
|
|
405
|
+
|
|
406
|
+
if self.steps.current == "confirm":
|
|
407
|
+
predictor = self.get_form("structure").save(commit=False)
|
|
408
|
+
model_file = self.get_cleaned_data_for_step("structure").get("config_file")
|
|
409
|
+
|
|
410
|
+
predictor.protocol = PredictorModel.Protocol.TYPE1
|
|
411
|
+
predictor.config_file = model_file
|
|
412
|
+
artist = predictor.runner.render()
|
|
413
|
+
glb = artist.canvas.to_glb()
|
|
414
|
+
glb64 = base64.b64encode(glb).decode("utf-8")
|
|
415
|
+
|
|
416
|
+
context["rndrdoc"] = escape(render_to_string(
|
|
417
|
+
"inventory/asset-on-map.html",
|
|
418
|
+
context={
|
|
419
|
+
"asset": self.asset,
|
|
420
|
+
"viewer": "three",
|
|
421
|
+
"scale": 1/3.2808, # TODO
|
|
422
|
+
# "offset": json.dumps(list(reversed(list(self.asset.coordinates)))),
|
|
423
|
+
"rotate": "[0, 0, 0]",
|
|
424
|
+
"render_glb": f"data:application/octet-stream;base64,{glb64}",
|
|
425
|
+
"location": json.dumps(list(reversed(list(self.asset.coordinates)))),
|
|
426
|
+
},
|
|
427
|
+
request=self.request
|
|
428
|
+
))
|
|
429
|
+
return context
|
|
430
|
+
|
|
431
|
+
def done(self, form_list, form_dict, **kwargs):
|
|
432
|
+
# datum comes from select step unless create step ran
|
|
433
|
+
if "select datum" in form_dict:
|
|
434
|
+
datum = form_dict["select datum"].cleaned_data["datum"]
|
|
435
|
+
elif "datum create" in form_dict:
|
|
436
|
+
datum = form_dict["datum create"].save(commit=False)
|
|
437
|
+
datum.save()
|
|
438
|
+
else:
|
|
439
|
+
datum = form_dict["select datum"].cleaned_data["datum"]
|
|
440
|
+
|
|
441
|
+
predictor = form_dict["structure"].save(commit=False)
|
|
442
|
+
sensor = form_dict["sensor"].save(commit=False)
|
|
223
443
|
|
|
444
|
+
predictor.asset = self.asset
|
|
445
|
+
predictor.active = True
|
|
446
|
+
predictor.protocol = PredictorModel.Protocol.TYPE1
|
|
447
|
+
predictor.save()
|
|
448
|
+
|
|
449
|
+
sensor.node = -1
|
|
450
|
+
sensor.predictor = predictor
|
|
451
|
+
sensor.save()
|
|
452
|
+
return redirect("asset_predictors", calid=predictor.asset.calid)
|
|
453
|
+
|
|
224
454
|
@login_required(login_url="/login/")
|
|
225
455
|
def create_model(request, calid):
|
|
226
456
|
|
|
@@ -252,6 +482,7 @@ def create_model(request, calid):
|
|
|
252
482
|
except Exception as e:
|
|
253
483
|
return HttpResponse(r400.render({"message": json.dumps({"error": str(e)})}), status=500)
|
|
254
484
|
|
|
485
|
+
|
|
255
486
|
# 3) Render the model
|
|
256
487
|
outlines = collect_outlines(csi, model.frame_tags)
|
|
257
488
|
artist = veux.create_artist(model,
|
|
@@ -5577,7 +5577,7 @@ textarea.form-control-lg {
|
|
|
5577
5577
|
--bs-accordion-body-padding-x: 1.25rem;
|
|
5578
5578
|
--bs-accordion-body-padding-y: 1rem;
|
|
5579
5579
|
--bs-accordion-active-color: rgb(27.9, 36.9, 49.5);
|
|
5580
|
-
--bs-accordion-active-bg:
|
|
5580
|
+
--bs-accordion-active-bg: transparent;
|
|
5581
5581
|
}
|
|
5582
5582
|
|
|
5583
5583
|
.accordion-button {
|