Example #1
0
// 单侧放量
void OnOffsetSingleActFn()
{
	/*if (!QuickCheckValidLicense(SMART_PROFESSIONAL))
		return;*/

	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	DestroyAllDialog();
	CancelSelectDialog();
	Sleep(50);

	ProMdl pMdl = GetCurrentMdl();
	if (pMdl == NULL)
	{
		MessageBox(NULL, L"当前环境未发现模型!", L"提示", MB_OK|MB_ICONWARNING);
		return;
	}

	// 选择面
	vector<ProSelection> arrSelQlt;
	ShowMessageTip(L"Tips.选择要偏移的面...");
	if (SelectObject(arrSelQlt, "surface"))
	{
		// 输入偏离值
		double dOffset;
		ShowMessageTip(L"输入偏移量,不能为0,但可以为负值:");
		if (ProMessageDoubleRead(NULL, &dOffset) == PRO_TK_NO_ERROR)
		{
			// 判断面的方向
			ProModelitem itemSurf;
			ProSelectionModelitemGet(arrSelQlt[0], &itemSurf);
			ProSurface surf;
			ProGeomitemToSurface(&itemSurf, &surf);
			ProGeomitemdata* psrfdata;
			ProSurfaceDataGet(surf, &psrfdata);
			if (psrfdata->data.p_surface_data->orient == PRO_SURF_ORIENT_IN)
				dOffset = dOffset*(-1);
			ProGeomitemdataFree(&psrfdata);
			// 创建偏移特征
			int nOffsetID = OffsetSurfaceWithSide(pMdl, arrSelQlt[0], dOffset);
			if (nOffsetID > 0)
			{
				// 修改面颜色
				ProFeature feat;
				feat.id = nOffsetID;
				feat.type = PRO_FEATURE;
				feat.owner = pMdl;
				vector<ProModelitem> arrQuilts;
				ProFeatureGeomitemVisit(&feat, PRO_QUILT, FeatureGeomsGetAction, NULL, &arrQuilts);
				for (int i=0; i<arrQuilts.size(); i++)
					SetSurfColor(arrQuilts[i], 255, 215, 0);
			}
		}
	}
	InvalidateDrawing();
	ProMessageClear();
}
// 获取模型中类轴曲面集_过滤函数
ProError CSDMdlMachLongAxisCheck::GetSldAxisSurfaceFilter(ProSurface pSurf, ProAppData pData)
{
    pData;

    ProGeomitemdata *pGeomData = NULL;
    ProSurfaceDataGet(pSurf, &pGeomData);
    ProError status = PRO_TK_CONTINUE;
    if (pGeomData->data.p_surface_data->type == PRO_SRF_CYL ||
            pGeomData->data.p_surface_data->type == PRO_SRF_CONE)
        status = PRO_TK_NO_ERROR;
    ProGeomitemdataFree(&pGeomData);

    return status;
}
ProError CSDMdl505PolarCheck::SurfaceVisitAction(ProSurface pSurf, ProError status, ProAppData pData)
{
	UNUSED_ALWAYS(status);

	PolarCylVisitData &visitData = *((PolarCylVisitData*)pData);

	ProGeomitemdata* pgdata;
	if (ProSurfaceDataGet(pSurf, &pgdata) == PRO_TK_NO_ERROR)
	{
		if (pgdata->data.p_surface_data->type == PRO_SRF_CYL)
		{
			visitData.line[0] = pgdata->data.p_surface_data->srf_shape.cylinder.e3[0];
			visitData.line[1] = pgdata->data.p_surface_data->srf_shape.cylinder.e3[1];
			visitData.line[2] = pgdata->data.p_surface_data->srf_shape.cylinder.e3[2];
			visitData.pt[0] = pgdata->data.p_surface_data->srf_shape.cylinder.origin[0];
			visitData.pt[1] = pgdata->data.p_surface_data->srf_shape.cylinder.origin[1];
			visitData.pt[2] = pgdata->data.p_surface_data->srf_shape.cylinder.origin[2];
			ProGeomitemdataFree(&pgdata);
			return PRO_TK_USER_ABORT;
		}
		ProGeomitemdataFree(&pgdata);
	}
	return PRO_TK_NO_ERROR;
}
// 获取曲面数据
BOOL CSDMdlMachLongAxisCheck::SetSurfaceData(ProSurface pSurf, ProSurface pSameSurf, SDC_SurfaceData &surfData)
{
    if (NULL == pSurf)
        return FALSE;

    surfData.pSurface = pSurf;
    surfData.pSameSurf = pSameSurf;
    ProGeomitemdata *pGeomData = NULL;
    ProSurfaceDataGet(pSurf, &pGeomData);
    BOOL bRet = FALSE;
    if (pGeomData->data.p_surface_data->type == PRO_SRF_CYL)
    {
        VectorCopy(pGeomData->data.p_surface_data->srf_shape.cylinder.origin, surfData.origin);
        VectorCopy(pGeomData->data.p_surface_data->srf_shape.cylinder.e3, surfData.axisVector);
        VectorCopy(pGeomData->data.p_surface_data->xyz_min, surfData.minPt);
        VectorCopy(pGeomData->data.p_surface_data->xyz_max, surfData.maxPt);
        SVDOUBLE3 minProj, maxProj;
        ProjectPtToLine(SVDOUBLE3(pGeomData->data.p_surface_data->srf_shape.cone.origin),
                        SVDOUBLE3(pGeomData->data.p_surface_data->srf_shape.cone.e3), SVDOUBLE3(surfData.minPt), minProj);
        ProjectPtToLine(SVDOUBLE3(pGeomData->data.p_surface_data->srf_shape.cone.origin),
                        SVDOUBLE3(pGeomData->data.p_surface_data->srf_shape.cone.e3), SVDOUBLE3(surfData.maxPt), maxProj);
        surfData.dDiameter = pGeomData->data.p_surface_data->srf_shape.cylinder.radius * 2.0;
        SVDOUBLE3ToPoint3D(minProj, surfData.minPt);
        SVDOUBLE3ToPoint3D(maxProj, surfData.maxPt);
        bRet = TRUE;
    }
    else if (pGeomData->data.p_surface_data->type == PRO_SRF_CONE)
    {
        VectorCopy(pGeomData->data.p_surface_data->srf_shape.cone.origin, surfData.origin);
        VectorCopy(pGeomData->data.p_surface_data->srf_shape.cone.e3, surfData.axisVector);
        VectorCopy(pGeomData->data.p_surface_data->xyz_min, surfData.minPt);
        VectorCopy(pGeomData->data.p_surface_data->xyz_max, surfData.maxPt);
        SVDOUBLE3 minProj, maxProj;
        ProjectPtToLine(SVDOUBLE3(pGeomData->data.p_surface_data->srf_shape.cone.origin),
                        SVDOUBLE3(pGeomData->data.p_surface_data->srf_shape.cone.e3), SVDOUBLE3(surfData.minPt), minProj);
        ProjectPtToLine(SVDOUBLE3(pGeomData->data.p_surface_data->srf_shape.cone.origin),
                        SVDOUBLE3(pGeomData->data.p_surface_data->srf_shape.cone.e3), SVDOUBLE3(surfData.maxPt), maxProj);
        double dR1 = CalculateDistance(SVDOUBLE3(surfData.minPt), SVDOUBLE3(minProj));
        double dR2 = CalculateDistance(SVDOUBLE3(surfData.maxPt), SVDOUBLE3(maxProj));
        surfData.dDiameter = dR1 < dR2 ? (dR1 * 2.0) : (dR2 * 2.0);
        VectorCopy(minProj, surfData.minPt);
        VectorCopy(maxProj, surfData.maxPt);
        bRet = TRUE;
    }
    ProGeomitemdataFree(&pGeomData);

    return TRUE;
}
// 判断圆柱面或圆锥面的法向是否远离轴线
BOOL CSDMdlMachLongAxisCheck::IsSurfNormalAwayFromAxis(ProSurface pSurf)
{
    if (NULL == pSurf)
        return FALSE;

    ProGeomitemdata *pSurfData = NULL;
    ProSurfaceDataGet(pSurf, &pSurfData);
    BOOL bRet = FALSE;
    if (pSurfData->data.p_surface_data->type == PRO_SRF_CYL ||
            pSurfData->data.p_surface_data->type == PRO_SRF_CONE)
    {
        if (pSurfData->data.p_surface_data->orient == PRO_SURF_ORIENT_OUT)
            bRet = TRUE;
    }

    ProGeomitemdataFree(&pSurfData);
    return bRet;
}
// 得到相接的边
ProEdge CSDMdlMachLongAxisCheck::GetCloseEdge(const ProPoint3d pt, ProContourdata *pContourArr)
{
    if (NULL == m_pCurSld)
        return NULL;
    if (pContourArr == NULL)
        return NULL;

    int nCounterSize = -1;
    ProArraySizeGet(pContourArr, &nCounterSize);
    int nEdgeSize = -1;
    ProEdge pEdge = NULL, pRetEdge = NULL;
    ProEnttype entType;
    ProError status = PRO_TK_GENERAL_ERROR;
    ProGeomitemdata *pEdgeData = NULL;
    for (int i=0; i<nCounterSize; i++)
    {
        ProContourdata &contour = pContourArr[i];
        ProArraySizeGet(contour.edge_id_arr, &nEdgeSize);
        for (int j=0; j<nEdgeSize; j++)
        {
            status = ProEdgeInit(m_pCurSld, contour.edge_id_arr[j], &pEdge);
            if (status != PRO_TK_NO_ERROR || pEdge == NULL)
                continue;

            ProEdgeTypeGet(pEdge, &entType);
            if (entType != PRO_ENT_ARC)
                continue;
            ProEdgeDataGet(pEdge, &pEdgeData);
            if (IsPntCoincide(pEdgeData->data.p_curve_data->arc.origin, pt))
                pRetEdge = pEdge;
            ProGeomitemdataFree(&pEdgeData);
            if (pRetEdge != NULL)
                break;
        }
        if (pRetEdge != NULL)
            break;
    }

    return pRetEdge;
}
// 根据参数得到相邻的曲面
ProSurface CSDMdlMachLongAxisCheck::GetNeighborSurf(const SDC_SurfaceData &surfData, BOOL bIsMinPara)
{
    ProSurface pSurf = surfData.pSurface;
    ProSurface pNeighborSurf = NULL;
    ProGeomitemdata *pGeomData = NULL;
    ProSurfaceDataGet(pSurf, &pGeomData);

    ProEdge pCloseEdge = GetCloseEdge(bIsMinPara ? surfData.minPt : surfData.maxPt, pGeomData->data.p_surface_data->contour_arr);
    if (pCloseEdge != NULL)
    {
        ProEdge pEdge1, pEdge2;
        ProSurface pFace1, pFace2;
        ProEdgeNeighborsGet(pCloseEdge, &pEdge1, &pEdge2, &pFace1, &pFace2);
        if (pFace1 == pSurf)
            pNeighborSurf = pFace2;
        else
            pNeighborSurf = pFace1;
    }

    ProGeomitemdataFree(&pGeomData);
    return pNeighborSurf;
}
// 检查开始,传出检查结果
int CSDMdl505PolarCheck::CheckAction(void *pData, const CheckRule &checkRule, CheckResult &checkResult)
{
	checkRule;
	ProMdl pMdl = (ProMdl)pData;
	if (NULL == pMdl)
	{
		checkResult.nResultType = CHECK_RESULT_INVALID_MODEL;
		return checkResult.nResultType;
	}

	if (!IsMdlTypeValid(pMdl, checkRule.dwMdlFilter))
	{
		checkResult.nResultType = CHECK_RESULT_INVALID_MODEL;
		return checkResult.nResultType;
	}

	// 获取坐标系对
	CsysPolarVisitData visitData;
	visitData.pMdl = pMdl;
	visitData.bCheck1 = TRUE;
	ProSolidCsysVisit((ProSolid)pMdl,
		CsyVisitAction,
		NULL,
		&visitData);

	// 判断模型是否包含圆柱曲面
	BOOL bFindCyl = FALSE;
	PolarCylVisitData cyldata;
	if (ProSolidSurfaceVisit(ProMdlToSolid(pMdl), SurfaceVisitAction, NULL, &cyldata) == PRO_TK_USER_ABORT)
	{
		bFindCyl = TRUE;
	}
	
	checkResult.arrErrorItems.RemoveAll();
	ErrorItem item;
	for (int i=0; i<visitData.arrID1.GetCount(); i++)
	{
		ProCsys pCsy1, pCsy2;
		ProCsysInit(ProMdlToSolid(pMdl), visitData.arrID1[i], &pCsy1);
		ProCsysInit(ProMdlToSolid(pMdl), visitData.arrID2[i], &pCsy2);
		ProGeomitemdata* pcsyData1, *pcsyData2;
		ProCsysDataGet(pCsy1, &pcsyData1);
		ProCsysDataGet(pCsy2, &pcsyData2);
		SVDOUBLE3 vec0, vec1, vec2, pt1, pt2;
		vec0.x = pcsyData2->data.p_csys_data->origin[0]-pcsyData1->data.p_csys_data->origin[0];
		vec0.y = pcsyData2->data.p_csys_data->origin[1]-pcsyData1->data.p_csys_data->origin[1];
		vec0.z = pcsyData2->data.p_csys_data->origin[2]-pcsyData1->data.p_csys_data->origin[2];
		vec1.x = pcsyData1->data.p_csys_data->z_vector[0];
		vec1.y = pcsyData1->data.p_csys_data->z_vector[1];
		vec1.z = pcsyData1->data.p_csys_data->z_vector[2];
		vec2.x = pcsyData2->data.p_csys_data->z_vector[0];
		vec2.y = pcsyData2->data.p_csys_data->z_vector[1];
		vec2.z = pcsyData2->data.p_csys_data->z_vector[2];
		pt1.x = pcsyData1->data.p_csys_data->origin[0];
		pt1.y = pcsyData1->data.p_csys_data->origin[1];
		pt1.z = pcsyData1->data.p_csys_data->origin[2];
		pt2.x = pcsyData2->data.p_csys_data->origin[0];
		pt2.y = pcsyData2->data.p_csys_data->origin[1];
		pt2.z = pcsyData2->data.p_csys_data->origin[2];
		ProGeomitemdataFree(&pcsyData1);
		ProGeomitemdataFree(&pcsyData2);
		BPVec3Normalize(&vec0, &vec0);
		BPVec3Normalize(&vec1, &vec1);
		BPVec3Normalize(&vec2, &vec2);

		// 检查是否指向模型本体外
		double dRadian = BPCalcArcCos(BPVec3Dot(vec0, vec1));
		if (!ISDNEAR(dRadian, 1.5707964) && dRadian < 1.5707964)
		{
			item.nID = visitData.arrID1[i];
			item.nType = PRO_CSYS;
			item.pOwner = pMdl;
			item.strItemName = visitData.arrCsysName[i] + L"1";
			checkResult.arrErrorItems.Add(item);
		}
		else if (bFindCyl)	// 检查是否同轴
		{
			if ((!IsVecSameDir(vec1, cyldata.line) && !IsVecReverseDir(vec1, cyldata.line)) || 
				!IsPointOnLine(pt1, vec1, cyldata.pt))
			{
				item.nID = visitData.arrID1[i];
				item.nType = PRO_CSYS;
				item.pOwner = pMdl;
				item.strItemName = visitData.arrCsysName[i] + L"1";
				checkResult.arrErrorItems.Add(item);
			}
		}
		dRadian = BPCalcArcCos(BPVec3Dot(vec0, vec2));
		if (!ISDNEAR(dRadian, 1.5707964) && dRadian > 1.5707964)
		{
			item.nID = visitData.arrID2[i];
			item.nType = PRO_CSYS;
			item.pOwner = pMdl;
			item.strItemName = visitData.arrCsysName[i] + L"2";
			checkResult.arrErrorItems.Add(item);
		}
		else if (bFindCyl)
		{
			if ((!IsVecSameDir(vec2, cyldata.line) && !IsVecReverseDir(vec2, cyldata.line)) || 
				!IsPointOnLine(pt2, vec2, cyldata.pt))
			{
				item.nID = visitData.arrID2[i];
				item.nType = PRO_CSYS;
				item.pOwner = pMdl;
				item.strItemName = visitData.arrCsysName[i] + L"2";
				checkResult.arrErrorItems.Add(item);
			}
		}
	}

	if (checkResult.arrErrorItems.GetCount() > 0)
		checkResult.nResultType = CHECK_RESULT_INVALID_VALUE;
	else
		checkResult.nResultType = CHECK_RESULT_NO_ERROR;
	return checkResult.nResultType;
}