/// <summary> /// parse the DataModel section of the save file, and restore the scene/datamodel as necessary /// </summary> /// <param name="xml"></param> protected virtual void RestoreDataModel(XmlDocument xml) { // look up root datamodel (should only be one) XmlNodeList datamodels = xml.SelectNodes("//DataModel"); XmlNode datamodel = datamodels[0]; // find scan ScanSO scanSO = OG.Scene.FindSceneObjectsOfType <ScanSO>().FirstOrDefault(); if (scanSO == null) { throw new Exception("OGSerializer.RestoreDataModel: no ScanSO?"); } // [TODO] we have scanIn and scanOut, don't we?!? // start in scan state, restore the scan OGActions.RestoreSocketDesignFromScan(OG.Context, scanSO); // [TODO] should only do this transition if user has accepted scan // (probably should have some current-state field in datamodel) OG.TransitionToState(RectifyState.Identifier); // restore LegModel deformation ops XmlNodeList deformationOps = datamodel.SelectNodes("LegDeformOp"); foreach (XmlNode opNode in deformationOps) { string type = opNode.Attributes["OpType"].InnerText; string so_uuid = opNode.Attributes["SceneObjectUUID"].InnerText; if (type == typeof(EnclosedRegionOffsetOp).ToString()) { EnclosedPatchSO patchSO = OG.Scene.FindByUUID(so_uuid) as EnclosedPatchSO; var newOp = OGActions.AddNewRegionDeformation(patchSO, LegModel.LegDeformationTypes.Offset); double offset = 0.0f; if (double.TryParse(opNode.Attributes["Offset"].InnerText, out offset)) { (newOp as EnclosedRegionOffsetOp).PushPullDistance = offset; } } else if (type == typeof(EnclosedRegionSmoothOp).ToString()) { EnclosedPatchSO patchSO = OG.Scene.FindByUUID(so_uuid) as EnclosedPatchSO; var newOp = OGActions.AddNewRegionDeformation(patchSO, LegModel.LegDeformationTypes.Smooth); double smooth = 0.0f; if (double.TryParse(opNode.Attributes["Smooth"].InnerText, out smooth)) { (newOp as EnclosedRegionSmoothOp).SmoothAlpha = smooth; } double offset = 0.0f; if (double.TryParse(opNode.Attributes["Offset"].InnerText, out offset)) { (newOp as EnclosedRegionSmoothOp).OffsetDistance = offset; } } else if (type == typeof(PlaneBandExpansionOp).ToString()) { PlaneIntersectionCurveSO curveSO = OG.Scene.FindByUUID(so_uuid) as PlaneIntersectionCurveSO; var newOp = OGActions.AddNewPlaneBandExpansion(curveSO); double extent = 0.0f; if (double.TryParse(opNode.Attributes["Extent"].InnerText, out extent)) { (newOp as PlaneBandExpansionOp).BandDistance = extent; } double offset = 0.0f; if (double.TryParse(opNode.Attributes["Offset"].InnerText, out offset)) { (newOp as PlaneBandExpansionOp).PushPullDistance = offset; } Vector3d origin = TryParseVector3(opNode.Attributes["Origin"].InnerText); (newOp as PlaneBandExpansionOp).Origin = origin; Vector3d normal = TryParseVector3(opNode.Attributes["Normal"].InnerText); (newOp as PlaneBandExpansionOp).Normal = normal; } else if (type == typeof(LengthenOp).ToString()) { LengthenPivotSO pivotSO = OG.Scene.FindByUUID(so_uuid) as LengthenPivotSO; LengthenOp newOp = OGActions.AddNewLengthenOp(pivotSO); double offset = 0.0f; if (double.TryParse(opNode.Attributes["Distance"].InnerText, out offset)) { newOp.LengthenDistance = offset; } } } // if we have a trimloop, restore it TrimLoopSO trimSO = OG.Scene.FindSceneObjectsOfType <TrimLoopSO>().FirstOrDefault(); if (trimSO != null) { OG.TransitionToState(SocketDesignState.Identifier); OGActions.AddNewTrimCurve(trimSO); } // [TODO] restore socket enabled, parameters, etc }