private bool processInput(out PenetrUserTask userTask, ref BCOM.Point3d Point, BCOM.View View) { BCOM.Point3d point = Point; ensureLocateEnabled(ref point, View); userTask = singleModel_.UserTask; if (string.IsNullOrEmpty(userTask.Code)) { return(false); } BCOM.HitPath hitPath = App.CommandState.GetHitPath(); if (!userTask.IsManualRotateMode && hitPath != null) { BCOM.Element firstHitElem = hitPath.GetElementAt(1); //int type1 = (int)firstHitElem.Type; if (firstHitElem.IsPlanarElement()) { userTask.Rotation = App.Matrix3dFromRotationBetweenVectors( ZAxis, firstHitElem.AsPlanarElement().Normal); } else { // TODO обход по поверхностям var targetFaces = new List <TFCOM.TFBrepFace>(); TFCOM.TFBrepList brepList = AppTF.CreateTFBrep(); try { // может быть исключение brepList.InitFromElement(firstHitElem, App.ActiveModelReference); } catch (Exception) { } foreach (TFCOM.TFBrepFace faceList in brepList?.GetFacesEx()) { TFCOM.TFPlane tfPlane; if (faceList.IsPlanar(out tfPlane)) { //BCOM.ShapeElement shapeElement; //BCOM.Point3d[] verts; //faceList.AsTFBrepFace.GetVertexLocations(out verts); //BCOM.ShapeElement shape = App.CreateShapeElement1(null, verts); BCOM.Point3d closest; BCOM.Point3d normal; BCOM.Point2d param; // faceList.GetClosestPoint(out closest, out normal, out param, ref Point); tfPlane.GetNormal(out normal); if (faceList as TFCOM.TFBrepFaceListClass != null) { normal = App.Point3dNegate(normal); } userTask.Rotation = App.Matrix3dFromRotationBetweenVectors( ZAxis, normal); break; //if (closest.EqualsPoint(Point)) //{ // targetFaces.Add(faceList); //} } } ; } } if (userTask.IsAutoLength) { double thickness = 0.0; BCOM.Element locEl = app_.CommandState.LocateElement(ref Point, View, true); if (locEl != null && locEl.IsCellElement()) { TFCOM.TFElementList tfList = AppTF.CreateTFElement(); tfList.InitFromElement(locEl); int type = tfList.AsTFElement.GetApplicationType(); if (tfList.AsTFElement.GetIsFormType()) { TFCOM._TFFormRecipeList recipeList; tfList.AsTFElement.GetFormRecipeList(out recipeList); if (type == (int)TFFormTypeEnum.TF_SLAB_FORM_ELM) { var slab = (TFCOM.TFFormRecipeSlabList)recipeList; slab.AsTFFormRecipeSlab.GetThickness(out thickness); } else if (type == (int)TFFormTypeEnum.TF_LINEAR_FORM_ELM) { var wall = (TFCOM.TFFormRecipeLinearList)recipeList; wall.AsTFFormRecipeLinear.GetThickness(out thickness); } } } if (thickness > 0.0) { userTask.LengthCm = (int)Math.Ceiling(thickness) / 10; } else { userTask.LengthCm = 1; } } singleModel_.setLocation(point); // для обновления формы return(true); }
public static bool getFromElement(Element element, XDocument attrsXDoc, out OpeningTask task) { task = null; BCOM.Element bcomEl = element.ToElementCOM(); var tfEl = AppTF.CreateTFElement(); tfEl.InitFromElement(bcomEl); var tfElType = (TFCOM.TFdElementType)tfEl.AsTFElement.GetApplicationType(); //if (tfElType != TFCOM.TFdElementType.tfdElementTypeEBrep) //{ // return false; //} BCOM.CellElement cell = element.ToCellElementCOM(); var brep = AppTF.CreateTFBrep(); brep.InitFromElement(bcomEl, App.ActiveModelReference); BCOM.Point3d[] verts; brep.GetVertexLocations(out verts); if (verts == null || verts.Count() < 8) { return(false); } if (verts.Count() > 8) { // встречались случаи с количеством вершин 24 шт. verts = new HashSet <BCOM.Point3d>(verts).Take(8).ToArray(); } var formsIntersected = new List <TFCOM.TFElementList>(); { // Пересечения со стеной/плитой/аркой; foreach (BCOM.Element current in bcomEl.scanIntersectsInElementRange()) { TFCOM.TFElementList tfList = AppTF.CreateTFElement(); tfList.InitFromElement(current); if (tfList.AsTFElement == null) { continue; } int tfType = tfList.AsTFElement.GetApplicationType(); if (isAvaliableTFFromType(tfType)) { //if (tfList.AsTFElement.GetIsFormType()) //{ formsIntersected.Add(tfList); //} } } } var planeFirst = new BCOM.Plane3d(); var planeSecond = new BCOM.Plane3d(); TFFormTypeEnum formType = TFFormTypeEnum.UNDEFINED; bool planesAreFound = false; if (formsIntersected.Count > 0) { // todo определение граней параллельных поверхности стены/плиты/арки; var tfElement = formsIntersected.First().AsTFElement; BCOM.Element formElement; tfElement.GetElement(out formElement); formType = ElementHelper.ParseFormType(tfElement.GetApplicationType()); switch (formType) { case TFFormTypeEnum.TF_LINEAR_FORM_ELM: planesAreFound = ElementHelper.getFacePlaneByLabel(out planeFirst, formElement, TFCOM.TFdFaceLabel.tfdFaceLabelLeft); planesAreFound &= ElementHelper.getFacePlaneByLabel(out planeSecond, formElement, TFCOM.TFdFaceLabel.tfdFaceLabelRight); break; case TFFormTypeEnum.TF_SLAB_FORM_ELM: planesAreFound = ElementHelper.getFacePlaneByLabel(out planeFirst, formElement, TFCOM.TFdFaceLabel.tfdFaceLabelTop); planesAreFound &= ElementHelper.getFacePlaneByLabel(out planeSecond, formElement, TFCOM.TFdFaceLabel.tfdFaceLabelBase); break; case TFFormTypeEnum.TF_ARC_FORM_ELM: // TODO РАДИАЛЬНЫЕ СТЕНЫ break; case TFFormTypeEnum.TF_EBREP_ELM: case TFFormTypeEnum.TF_SMOOTH_FORM_ELM: TFCOM.TFBrepList brepList = AppTF.CreateTFBrep(); brepList.InitFromElement(formElement, App.ActiveModelReference); planesAreFound = ElementHelper.getFacePlaneByLabel(out planeFirst, brepList, TFCOM.TFdFaceLabel.tfdFaceLabelTop); var intersectedPlanes = new List <TFCOM.TFPlane>(); TFCOM.TFPlane tfPlane; IEnumerable <TFCOM.TFBrepFace> faceLists = brepList.GetFacesEx(); foreach (var faceList in faceLists) { if (faceList.IsPlanarAndIntersectsElement(bcomEl, out tfPlane)) { intersectedPlanes.Add(tfPlane); } } if (intersectedPlanes.Count > 2) { // TODO ?? /* * 1. собрать коллекцию с суммой площадей параллельных поверхностей * 2. у большей коллекции по суммарной площади вычислить нормаль * 3. выбирать плоскости проекции задания в соответсвии с выбранной нормалью */ var facesInfo = new List <FaceInfo>(); foreach (var faceList in faceLists) { TFCOM.TFPlane faceTFPlane; if (faceList.IsPlanar(out faceTFPlane)) { double area; faceList.GetArea(out area, string.Empty); BCOM.Plane3d plane3D = faceTFPlane.ToPlane3d(); FaceInfo faceInfo = facesInfo.FirstOrDefault(x => x.Normal.IsVectorParallelTo(plane3D.Normal)); if (faceInfo.Area == 0) { facesInfo.Add(new FaceInfo() { Area = area, Normal = plane3D.Normal }); } else { faceInfo.Area += area; } } } facesInfo.Sort((x, y) => - 1 * x.Area.CompareTo(y.Area)); FaceInfo faceTarget = facesInfo[0]; intersectedPlanes.RemoveAll((x) => { BCOM.Point3d norm; x.GetNormal(out norm); return(!norm.IsVectorParallelTo(faceTarget.Normal)); }); ; } if (intersectedPlanes.Count == 2) { // ! должно выполняться условие параллельности planeFirst = intersectedPlanes[0].ToPlane3d(); planeSecond = intersectedPlanes[1].ToPlane3d(); planesAreFound = planeFirst.IsParallelTo(planeSecond); } { /* TODO * Если только одна поверхность: * 1. через точку контура провести нормаль * 2. найти поверхности, кот. пересекает нормаль */ } break; } } if (!planesAreFound) { return(false); } { // корректировка плоскостей относительно пользователя BCOM.Point3d projOrigin = planeFirst.Origin.ProjectToPlane3d(planeSecond); switch (formType) { case TFFormTypeEnum.TF_LINEAR_FORM_ELM: if ((int)projOrigin.Y < (int)planeFirst.Origin.Y || (int)projOrigin.X > (int)planeFirst.Origin.X) { BCOM.Plane3d buff = planeFirst; planeFirst = planeSecond; planeSecond = buff; } break; case TFFormTypeEnum.TF_SLAB_FORM_ELM: case TFFormTypeEnum.TF_FREE_FORM_ELM: if ((int)projOrigin.Z > (int)planeFirst.Origin.Z) { BCOM.Plane3d buff = planeFirst; planeFirst = planeSecond; planeSecond = buff; } break; } } { // Определение параметров контура: var sorted = new List <VertexInfo>(); foreach (BCOM.Point3d pt in verts) { var projPt = pt.ProjectToPlane3d(planeFirst); sorted.Add(new VertexInfo() { Distance = App.Point3dDistance(pt, projPt), Point = projPt }); } sorted.Sort(); var firstFaceBounds = sorted.Take(4).Select(x => x.Point); var checkSet = new HashSet <BCOM.Point3d>(firstFaceBounds); if (checkSet.Count < 4) { return(false); } sorted.Clear(); foreach (BCOM.Point3d pt in verts) { var projPt = pt.ProjectToPlane3d(planeSecond); sorted.Add(new VertexInfo() { Distance = App.Point3dDistance(pt, projPt), Point = projPt }); } sorted.Sort(); var secondFaceBounds = sorted.Take(4).Select(x => x.Point); checkSet = new HashSet <BCOM.Point3d>(secondFaceBounds); if (checkSet.Count < 4) { return(false); } var pts = firstFaceBounds.ToArray(); var dimensions = new List <DimensionInfo>() { new DimensionInfo(pts[0], pts[1]), new DimensionInfo(pts[0], pts[2]), new DimensionInfo(pts[0], pts[3]), }; dimensions.Sort(); if (planeFirst.IsParallelTo(App.GetPlane3dXY())) { // TOTO ширина и высота относительно ориентации } // опорная точка Origin: //contourOrigin BCOM.ShapeElement contour = App.CreateShapeElement1(null, pts); BCOM.Point3d projOriginFirst = contour.Centroid().ProjectToPlane3d(planeFirst); task = new OpeningTask(); { // инициализация объекта задания XDocument xDoc = ElementHelper.getSp3dXDocument(element); xDoc.Merge(attrsXDoc); Sp3dToDGMapping.Instance.LoadValuesFromXDoc(xDoc, task.DataGroupPropsValues); // TODO //task.Code = xDoc.Root. // getChildByRegexPath("P3DEquipment/Name", out propName)?.Value; //string propName; task.Origin = projOriginFirst; { // Высота task.Height = dimensions[0].Length; task.HeigthVec = App.Point3dNormalize(dimensions[0].Vector); } { // Ширина task.Width = dimensions[1].Length; task.WidthVec = App.Point3dNormalize(dimensions[1].Vector); } { // Глубина BCOM.Point3d projOriginSecond = projOriginFirst.ProjectToPlane3d(planeSecond); task.Depth = Math.Round( App.Point3dDistance(projOriginFirst, projOriginSecond), 5); task.DepthVec = App.Point3dNormalize( App.Point3dSubtract(projOriginSecond, projOriginFirst)); } } } return(true); }