void SmoothTris() { int rows = triGrid.GetLength(0); int cols = triGrid.GetLength(1); TriType[,] newTris = new TriType[rows, cols]; for (int row = 0; row < rows; row++) { int tris = GetTrisInRow(row); int startTri = (cols - tris) / 2; for (int col = startTri, endTri = tris + startTri; col < endTri; col++) { newTris [row, col] = GetSmoothTriType(row, col, rows, tris, true); } } triGrid = newTris; }
float GetHeight(TriType triType) { if (triType == TriType.Abyss) { return(-1f); } else if (triType == TriType.Wall) { return(1f); } else if (triType == TriType.Ground) { return(0f); } else { return(-1.5f); } }
Vector2 GetUVCoordinate(TriType triType) { if (triType == TriType.Ground) { return(new Vector2(0.5f, 0.5f)); } else if (triType == TriType.Abyss) { return(new Vector2(0.5f, 0.2f)); } else if (triType == TriType.Wall) { return(new Vector2(0.5f, 0.8f)); } else { return(new Vector2(0.5f, 0.1f)); } }
public override void OnMouseDown(int Button, int Shift, int X, int Y) { // TODO: Add ToolAddCraterOnTIN.OnMouseDown implementation if (pTinLayer != null) { ITin pTin = pTinLayer.Dataset; ISurface pSurface = ((ITinAdvanced)pTin).Surface; IMapControl2 pMapCtr = (((IToolbarControl)m_hookHelper.Hook).Buddy) as IMapControl2; //在mapctr操作 if (pMapCtr != null) { IPoint mapPoint = pMapCtr.ToMapPoint(X, Y); IZAware za = mapPoint as IZAware; za.ZAware = true; double zVal; zVal = pSurface.GetElevation(mapPoint); if (double.IsNaN(zVal)) { MessageBox.Show("获取模型的高度失败!"); return; } if (m_listModels.Count == 0) { MessageBox.Show("请先生成模型!"); return; } mapPoint.Z = zVal; try { //IMultiPatch pMP = new MultiPatchClass(); IFeatureClass pFC = pFeatureLayer.FeatureClass; IFeature pF = pFC.CreateFeature(); IImport3DFile pI3D = new Import3DFileClass(); pI3D.CreateFromFile(m_listModels[m_listModels.Count - 1]); IMultiPatch pMP = pI3D.Geometry as IMultiPatch; ITransform3D pT3D = pMP as ITransform3D; pT3D.Move3D(mapPoint.X, mapPoint.Y, mapPoint.Z); pF.Shape = pMP as IGeometry; pF.Store(); if (pMapCtr != null) { pMapCtr.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null); } } catch (SystemException e) { MessageBox.Show(e.Message); } //IMultiPatch pMP = new MultiPatchClass(); //for (int i = 0; i < 5; i++) //{ // IFeature pF = pFC.CreateFeature(); // IImport3DFile pI3D = new Import3DFileClass(); // pI3D.CreateFromFile(@"C:\Users\Administrator\Desktop\sampleAnalysis\1002.3ds"); // IMultiPatch pMP = pI3D.Geometry as IMultiPatch; // // ITransform3D pT3D = pMP as ITransform3D; // pF.Shape = pMP as IGeometry; // ITransform3D pT3D = pF.Shape as ITransform3D; // pT3D.Move3D(5293 + 1600, -20427 , 800 + i*400); // // pF.Shape = pI3D.Geometry; } } if (pRasterLayer != null) { //ITin pTin = pTinLayer.Dataset; //ISurface pSurface = ((ITinAdvanced)pTin).Surface; IMapControl2 pMapCtr = (((IToolbarControl)m_hookHelper.Hook).Buddy) as IMapControl2; //在mapctr操作 if (pMapCtr != null) { IPoint mapPoint = pMapCtr.ToMapPoint(X, Y); //添加手工编辑窗口 FrmManualSetModelPara pManualSetPara = null; if (m_pModel == null) { Pt2d ptCurrent = new Pt2d(); ptCurrent.X = mapPoint.X; ptCurrent.Y = mapPoint.Y; pManualSetPara = new FrmManualSetModelPara(ptCurrent, "Crater"); } else { m_pModel.x = mapPoint.X; m_pModel.y = mapPoint.Y; pManualSetPara = new FrmManualSetModelPara(m_pModel); } //FrmManualSetModelPara pManualSetPara = new FrmManualSetModelPara(ptCurrent, "Crater"); if (pManualSetPara.ShowDialog() == DialogResult.OK) { if (m_pModel == null) { m_pModel = new Model(); } bool bFlag = m_pModel.compareModelPara(pManualSetPara.m_pModel); if (!bFlag) //模型参数已经被修改,需要重新生成新的模型文件 { m_pModel.copyFromModel(pManualSetPara.m_pModel); //根据设置的参数生成相应的模型 TriType triType = TriType.TriForward; LibModelGen.MappingType mappingType = LibModelGen.MappingType.Flat; String szModelOutputFilename = System.IO.Path.GetTempFileName(); szModelOutputFilename = szModelOutputFilename.Substring(0, szModelOutputFilename.LastIndexOf('.')) + ".3ds"; ModelBase crater = new CraterGen(m_pModel.dbSize, m_pModel.dbDepth); crater.OutputFilename = szModelOutputFilename; crater.triype = triType; crater.mappingType = mappingType; //将撞击坑模型添加到相应图层 if (crater.generate()) { m_listModels.Add(szModelOutputFilename); } } //保存当前添加的模型参数 Model pTmpModel = new Model(); pTmpModel.copyFromModel(pManualSetPara.m_pModel); m_manualAddModels.Add(pTmpModel); } else { return; } IZAware za = mapPoint as IZAware; za.ZAware = true; double zVal; IRaster2 pRaster2 = pRasterLayer.Raster as IRaster2; int col, row; pRaster2.MapToPixel(mapPoint.X, mapPoint.Y, out col, out row); zVal = Convert.ToDouble(pRaster2.GetPixelValue(0, col, row)); if (double.IsNaN(zVal)) { MessageBox.Show("获取模型的高度失败!"); return; } if (m_listModels.Count == 0) { MessageBox.Show("请先生成模型!"); return; } mapPoint.Z = zVal; IFeature pfeature = null; try { //IMultiPatch pMP = new MultiPatchClass(); IFeatureClass pFC = pFeatureLayer.FeatureClass; IFeature pF = pFC.CreateFeature(); IImport3DFile pI3D = new Import3DFileClass(); pI3D.CreateFromFile(m_listModels[m_listModels.Count - 1]); IMultiPatch pMP = pI3D.Geometry as IMultiPatch; ITransform3D pT3D = pMP as ITransform3D; // pT3D.Move3D(mapPoint.X, mapPoint.Y, mapPoint.Z); pT3D.Move3D(pManualSetPara.m_pModel.x, pManualSetPara.m_pModel.y, mapPoint.Z); //IRasterProps pRasterProps = pRasterLayer.Raster as IRasterProps; //double xmax = pRasterProps.Extent.XMax; //double xmin = pRasterProps.Extent.XMin; //double ymax = pRasterProps.Extent.YMax; //double ymin = pRasterProps.Extent.YMin; ////生成地形的地理范围 //double dbGeoRangeX = xmax - xmin; //double dbGeoRangeY = ymax - ymin; //double dbModelRangeX = pMP.Envelope.Width; //double dbModelRangeY = pMP.Envelope.Height; //double dbModelRangeZ = pMP.Envelope.ZMax - pMP.Envelope.ZMin; //根据地形大小改变撞击坑大小 //double dbRandomSize = Math.Min(dbGeoRangeX, dbGeoRangeY) * (0.15); //[0.03 0.06] //double dbRandomSize = pRasterProps.MeanCellSize().X * 300; //double dbScale = pManualSetPara.m_pModel.dbSize;// / Math.Max(dbModelRangeX, dbModelRangeY); //pT3D.Scale3D(mapPoint, dbScale, dbScale, dbScale); pF.Shape = pMP as IGeometry; pfeature = pF as IFeature; pF.Store(); if (pMapCtr != null) { pMapCtr.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null); } } catch (SystemException e) { if (e.Message == "The spatial index grid size is invalid.") { IFeatureClassLoad pFCL = pFeatureLayer.FeatureClass as IFeatureClassLoad; pFCL.LoadOnlyMode = true; pfeature.Store(); pFCL.LoadOnlyMode = false; } else { MessageBox.Show(e.Message); } } } } }
static public bool mesh2Tri(Point3D[,] dbArray, double dbThreshold, out ushort[,] nFacesIndex, out double[,] dbVertices, TriType type) { nFacesIndex = null; dbVertices = null; if (dbArray == null) { return(false); } int nRows = dbArray.GetLength(0); int nCols = dbArray.GetLength(1); #region 判断产生的模型点是否在坑径范围内 bool[,] bFlags = new bool[nRows, nCols]; dbVertices = new double[nRows * nCols, 3]; for (int i = 0; i < nRows; i++) { for (int j = 0; j < nCols; j++) { double dbX = dbArray[i, j].X; double dbY = dbArray[i, j].Y; double dbZ = dbArray[i, j].Z; dbVertices[i * nCols + j, 0] = dbX; dbVertices[i * nCols + j, 1] = dbY; dbVertices[i * nCols + j, 2] = dbZ; if (Math.Sqrt(dbX * dbX + dbY * dbY) <= dbThreshold) { bFlags[i, j] = true; } else { bFlags[i, j] = false; } } } #endregion #region 构面 //分别记录坑径范围内的点构成面的各节点的索引 List <Point3D> listFaces = new List <Point3D>(); switch (type) { case TriType.TriForward: for (int i = 0; i < nRows - 1; i++) { for (int j = 0; j < nCols - 1; j++) { if (bFlags[i, j] && bFlags[i + 1, j] && bFlags[i, j + 1]) { listFaces.Add(new Point3D(i * nCols + j, (i + 1) * nCols + j, i * nCols + j + 1)); } if (bFlags[i + 1, j + 1] && bFlags[i, j + 1] && bFlags[i + 1, j]) { listFaces.Add(new Point3D((i + 1) * nCols + j + 1, i * nCols + j + 1, (i + 1) * nCols + j)); } } } break; case TriType.TriBackward: for (int i = 0; i < nRows - 1; i++) { for (int j = 0; j < nCols - 1; j++) { if (bFlags[i, j] && bFlags[i + 1, j] && bFlags[i + 1, j + 1]) { listFaces.Add(new Point3D(i * nCols + j, (i + 1) * nCols + j, (i + 1) * nCols + j + 1)); } if (bFlags[i, j] && bFlags[i, j + 1] && bFlags[i + 1, j + 1]) { listFaces.Add(new Point3D(i * nCols + j, i * nCols + j + 1, (i + 1) * nCols + j + 1)); } } } break; default: break; } #endregion #region int nFaceCount = listFaces.Count; nFacesIndex = new ushort[nFaceCount, 3]; for (int i = 0; i < nFaceCount; i++) { nFacesIndex[i, 0] = (ushort)listFaces[i].X; nFacesIndex[i, 1] = (ushort)listFaces[i].Y; nFacesIndex[i, 2] = (ushort)listFaces[i].Z; } #endregion return(true); }
Vector3[] GetMeshVerts(int triCount, out Vector3[] extraNorms, out List <TriType> xtraLvls) { Vector3[] verts = new Vector3[triCount * 3]; // Debug.Log (verts.Length); int rows = Rows; xtraLvls = new List <TriType> (); List <Vector3> wallNorms = new List <Vector3> (); List <Vector3> xtraVerts = new List <Vector3> (); int maxCols = MaxCols; int idVert = 0; bool subDiv1 = meshSubdivisionLvl != 1; float step = size / rows; int prevRow = 0; float zFactor = Mathf.Sqrt(3) / 2; float rimHeight = GetHeight(TriType.None) * heightFactor; TriType prevLvl = TriType.None; TriType lvl = TriType.None; Dictionary <float, TriType> heightLookup = new Dictionary <float, TriType> (); heightLookup [GetHeight(TriType.Abyss) * heightFactor] = TriType.Abyss; heightLookup [GetHeight(TriType.Ground) * heightFactor] = TriType.Ground; heightLookup [GetHeight(TriType.Wall) * heightFactor] = TriType.Wall; for (int row = 0; row < rows; row++) { int trisInRow = GetTrisInRow(row); int startTri = (maxCols - trisInRow) / 2; for (int col = startTri, endTri = trisInRow + startTri; col < endTri; col++) { lvl = triGrid [row, col]; float y = GetHeight(lvl) * heightFactor; float x = step * (col - maxCols / 2f + 0.5f); float z = 2 * step * (row - rows / 2f + 0.5f) * zFactor; if (col % 2 == row % 2 != subDiv1) { verts [idVert] = new Vector3(x, y, z - step * zFactor); verts [idVert + 2] = new Vector3(x + step, y, z + step * zFactor); verts [idVert + 1] = new Vector3(x - step, y, z + step * zFactor); if (fillVerticals && col != startTri && triGrid [row, col] != triGrid [row, col - 1]) { xtraVerts.Add(verts[idVert - 2]); xtraLvls.Add(prevLvl); xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert - 1]); xtraLvls.Add(prevLvl); xtraVerts.Add(verts[idVert - 2]); xtraLvls.Add(prevLvl); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); for (int i = 0; i < 6; i++) { wallNorms.Add(Vector3.left); } } if (IsEdgeLocalN(row)) { xtraVerts.Add(new Vector3(x + step, rimHeight, z + step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(new Vector3(x - step, rimHeight, z + step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(verts[idVert + 2]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(new Vector3(x + step, rimHeight, z + step * zFactor)); xtraLvls.Add(TriType.None); for (int i = 0; i < 6; i++) { wallNorms.Add(Vector3.back); } } if (IsEdgeLocalSW(row, col)) { xtraVerts.Add(new Vector3(x - step, rimHeight, z + step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(new Vector3(x, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(new Vector3(x, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); for (int i = 0; i < 6; i++) { wallNorms.Add(Vector3.left); } } if (IsEdgeLocalSE(row, col)) { xtraVerts.Add(new Vector3(x + step, rimHeight, z + step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(new Vector3(x, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(verts[idVert + 2]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert + 2]); xtraLvls.Add(lvl); xtraVerts.Add(new Vector3(x, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); for (int i = 0; i < 6; i++) { wallNorms.Add(Vector3.forward); } } } else { verts [idVert] = new Vector3(x - step, y, z - step * zFactor); verts [idVert + 2] = new Vector3(x + step, y, z - step * zFactor); verts [idVert + 1] = new Vector3(x, y, z + step * zFactor); if (fillVerticals && col != startTri && triGrid [row, col] != triGrid [row, col - 1]) { xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert - 1]); xtraLvls.Add(prevLvl); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert - 3]); xtraLvls.Add(prevLvl); xtraVerts.Add(verts[idVert - 1]); xtraLvls.Add(prevLvl); for (int i = 0; i < 6; i++) { wallNorms.Add(Vector3.right); } } if (fillVerticals && row > 0 && (col > startTri || row >= rows / 2) && triGrid [row, col] != triGrid [row - 1, col]) { int prevOffset = Mathf.Min(trisInRow, prevRow) + Mathf.Abs((prevRow - trisInRow) / 2); TriType otherLvl = triGrid [row - 1, col]; xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert - 3 * prevOffset + 2]); xtraLvls.Add(otherLvl); xtraVerts.Add(verts[idVert - 3 * prevOffset + 1]); xtraLvls.Add(otherLvl); xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert + 2]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert - 3 * prevOffset + 2]); xtraLvls.Add(otherLvl); for (int i = 0; i < 6; i++) { wallNorms.Add(Vector3.forward); } } if (IsEdgeLocalS(row)) { xtraVerts.Add(new Vector3(x + step, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(new Vector3(x - step, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert + 2]); xtraLvls.Add(lvl); xtraVerts.Add(new Vector3(x + step, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); for (int i = 0; i < 6; i++) { wallNorms.Add(Vector3.forward); } } if (IsEdgeLocalNE(row, col)) { xtraVerts.Add(new Vector3(x + step, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(new Vector3(x, rimHeight, z + step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(verts[idVert + 2]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(new Vector3(x + step, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); for (int i = 0; i < 6; i++) { wallNorms.Add(Vector3.forward); } } if (IsEdgeLocalNW(row, col)) { xtraVerts.Add(new Vector3(x - step, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(new Vector3(x, rimHeight, z + step * zFactor)); xtraLvls.Add(TriType.None); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert + 1]); xtraLvls.Add(lvl); xtraVerts.Add(verts[idVert]); xtraLvls.Add(lvl); xtraVerts.Add(new Vector3(x - step, rimHeight, z - step * zFactor)); xtraLvls.Add(TriType.None); for (int i = 0; i < 6; i++) { wallNorms.Add(Vector3.forward); } } } prevLvl = lvl; idVert += 3; } prevRow = trisInRow; } Vector3[] allVerts = new Vector3[verts.Length + xtraVerts.Count]; System.Array.Copy(verts, allVerts, verts.Length); System.Array.Copy(xtraVerts.ToArray(), 0, allVerts, verts.Length, xtraVerts.Count); extraNorms = wallNorms.ToArray(); return(allVerts); }
TriType GetSmoothTriType(int row, int col, int maxRows, int maxCols, bool pointsUp) { int[] votes = new int[4]; votes [(int)triGrid [row, col]] += 3; if (col > 0) { votes [(int)triGrid [row, col - 1]] += 2; } if (col < maxCols - 1) { votes[(int)triGrid[row, col + 1]] += 2; } if (col > 1) { votes [(int)triGrid [row, col - 2]] += 1; } if (col < maxCols - 2) { votes [(int)triGrid [row, col + 2]] += 1; } int dir = pointsUp ? -1 : 1; int row2 = row + dir; if (row2 >= 0 && row2 < maxRows) { votes [(int)triGrid [row2, col]] += 2; if (col > 0) { votes [(int)triGrid [row2, col - 1]] += 1; } if (col < maxCols - 1) { votes[(int)triGrid[row2, col + 1]] += 1; } if (col > 1) { votes [(int)triGrid [row2, col - 2]] += 1; } if (col < maxCols - 2) { votes [(int)triGrid [row2, col + 2]] += 1; } } int row3 = row - dir; if (row3 >= 0 && row3 < maxRows) { votes [(int)triGrid [row3, col]] += 2; if (col > 0) { votes [(int)triGrid [row3, col - 1]] += 1; } if (col < maxCols - 1) { votes[(int)triGrid[row3, col + 1]] += 1; } } TriType vote = TriType.None; int nVotes = 0; for (int i = 1; i < votes.Length; i++) { if (votes [i] > nVotes) { nVotes = votes [i]; vote = (TriType)i; } } return(vote); }