Files
envi-code/SourceCode/Code2026/tg_shs/shs_kerncmd/PathVideoDlg.cpp
T

568 lines
13 KiB
C++
Raw Normal View History

2026-09-28 15:28:50 +08:00
// PathVideoDlg.cpp : implementation file
//
#include "stdafx.h"
#if ADS<17
#include "actrans.h"
#include "avlib.h"
#include "Texture.h"
#include "PathVideoDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern void GetRectBmpFromBmp(CWnd *pWnd,CRect rectClient,CBitmap &bitmap);
extern CRect GetVPRect(int vport);
int CPathVideoDlg::m_nFrameNum = 100;
int CPathVideoDlg::m_nRate = 25;
int CPathVideoDlg::m_nColorNum = 3;
BOOL CPathVideoDlg::m_bRender = FALSE;
CPathVideoDlg::CPathVideoDlg(CWnd* pParent /*=NULL*/)
: GlwCAcUiDialog(CPathVideoDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CPathVideoDlg)
//}}AFX_DATA_INIT
m_bInit = FALSE;
m_bIsPathCam = FALSE;
m_bIsPathTar = FALSE;
m_nCount = 0;
m_bHasInitAvi = FALSE;
m_bTakePhoto = FALSE;
RBList rbMask(RTDXF0, _T("TCH_CAMERA"), NULL);
PickSet ss(SS_FREE);
if (ss.Get(_T("X"), NULL, NULL, rbMask)!=RTNORM) {
adsout << _T("\n请用相机透视建立一相机!");
m_bInit = FALSE;
return;
}
if (ss.Length()==1L)
m_id=ss[0L];
else if (SelectEntity(_T("\n请选择上华照相机<退出>:"), m_id, rbMask)!=RTNORM)
return;
m_bInit = TRUE;
m_rectVP = CRect(0,0,0,0);
}
void CPathVideoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPathVideoDlg)
DDX_Text(pDX, IDC_EDIT_FRAME_NUM, m_nFrameNum);
DDX_Text(pDX, IDC_EDIT_RATE, m_nRate);
DDV_MinMaxInt(pDX, m_nRate, 1, 200);
DDX_Check(pDX, IDC_CHECK_RENDER, m_bRender);
DDX_Radio(pDX, IDC_COLOR2, m_nColorNum);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPathVideoDlg, GlwCAcUiDialog)
//{{AFX_MSG_MAP(CPathVideoDlg)
ON_BN_CLICKED(IDC_CAMERA_PATH, OnCameraPath)
ON_BN_CLICKED(IDC_CAMERA_POINT, OnCameraPoint)
ON_BN_CLICKED(IDC_TARGET_PATH, OnTargetPath)
ON_BN_CLICKED(IDC_TARGET_POINT, OnTargetPoint)
ON_BN_CLICKED(IDC_PREVIEW, OnPreview)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CPathVideoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
return TRUE;
}
void CPathVideoDlg::HideDialog(BOOL Flag)
{
if (Flag) {
GetParent()->EnableWindow(TRUE);
GetParent()->SetFocus();
GetParent()->SetActiveWindow();
ShowWindow(SW_HIDE);
GetParent()->RedrawWindow();
}
else {
GetParent()->EnableWindow(FALSE);
EnableWindow(TRUE);
SetActiveWindow();
ShowWindow(SW_SHOW);
}
}
void CPathVideoDlg::OnCameraPath()
{
HideDialog(TRUE);
Entity ent;
RBList rbMask(RTDXF0, _T("LINE,ARC,CIRCLE,POLYLINE,LWPOLYLINE"), NULL);
if (SelectEntity(_T("\n请选择作为路径的曲线(线/弧/圆/多段线):"), ent, rbMask)==RTNORM) {
m_ePathCam=ent;
XPoly2D pathCamera(ent);
if (!pathCamera){
m_pathCamera.Reset();
XCurveSegment curve(ent);
curve.AsPoly2D(m_pathCamera);
}
else
m_pathCamera = pathCamera;
}
m_bIsPathCam = TRUE;
HideDialog(FALSE);
}
void CPathVideoDlg::OnCameraPoint()
{
HideDialog(TRUE);
if (!m_id) return;
XPoint pt;
OPENOBJ_BEGIN(m_id, AcDb::kForRead, TDbCamera, pCam);
if (pCam) {
pt = pCam->GetCamera();
}
OPENOBJ_END();
int ret = XGetPoint(Wcs2Ucs(pt), _T("\n点取照相机位置"), m_ptCamera);
if (ret != RTNORM)
m_ptCamera = pt;
else
m_ptCamera = Ucs2Wcs(m_ptCamera);
m_bIsPathCam = FALSE;
HideDialog(FALSE);
}
void CPathVideoDlg::OnTargetPath()
{
HideDialog(TRUE);
Entity ent;
RBList rbMask(RTDXF0, _T("LINE,ARC,CIRCLE,POLYLINE,LWPOLYLINE"), NULL);
if (SelectEntity(_T("\n请选择作为路径的曲线(线/弧/圆/多段线):"), ent, rbMask)==RTNORM) {
m_ePathTar = ent;
XPoly2D pathCamera(ent);
if (!pathCamera){
XCurveSegment curve(ent);
curve.AsPoly2D(m_pathTarget);
}
else
m_pathTarget = pathCamera;
m_bIsPathTar = TRUE;
}
HideDialog(FALSE);
}
void CPathVideoDlg::OnTargetPoint()
{
HideDialog(TRUE);
int ret = XGetPoint(NULL, _T("\n点取照相机位置"), m_ptTarget);
if (ret == RTNORM) {
m_ptTarget=Ucs2Wcs(m_ptTarget);
m_bIsPathTar = FALSE;
}
HideDialog(FALSE);
}
BOOL CPathVideoDlg::GetAviFile(CString& csAviFile)
{
XString sFileName;
if (GetFileDia(sFileName, 1, _T("avi"), _T("输入动画文件名"))!=RTNORM)
return FALSE;
if (FindFile(sFileName)) {
if (_tremove(sFileName) != 0) {
AfxMessageBox(_T("当前文件可能被打开或只读!"));
return FALSE;
}
}
csAviFile=(const TCHAR *)sFileName;
/*
CFileDialog dlg(TRUE,"*.avi",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("上华录影文件 (*.avi) |*.AVI||"),this); // sr modify
if (dlg.DoModal()!=IDOK){
return FALSE;
}
//if (FindFile(dlg.GetPathName())) {
// return FALSE;
//}
csAviFile = dlg.GetPathName();
*/
return TRUE;
}
void CPathVideoDlg::OnPreview()
{
UpdateData(TRUE);
if (!m_bIsPathCam && !m_bIsPathTar)
{
MessageBox(_T("相机路径和目标路径不能都选点!"));
return;
}
if (m_nFrameNum < 1)
{
MessageBox(_T("总帧数不能为0!\n\n注意:总帧数也不能定得太大,否则会影响预览速度。"));
return;
}
m_nCount = 0;
m_bTakePhoto = FALSE;
HideDialog(TRUE);
for(int i = 0; i < m_nFrameNum; i++)
{
TakePhoto();
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
}
HideDialog(FALSE);
}
void CPathVideoDlg::OnOK()
{
extern void SetSunLight();
extern void SetMaterial();
UpdateData(TRUE);
m_nCount = 0;
m_bTakePhoto = TRUE;
if (!m_bIsPathCam && !m_bIsPathTar) {
MessageBox(_T("相机路径和目标路径不能都选点!"));
return;
}
if (m_nFrameNum<1) {
MessageBox(_T("总帧数不能为0!\n注意:总帧数也不能定得太大,否则会影响预览速度。"));
return;
}
HideDialog(TRUE);
CString csAviFile;
if (!GetAviFile(csAviFile)) {
m_nCount = m_nFrameNum;
HideDialog(FALSE);
return;
}
int nVP=0;
OPENOBJ_BEGIN(m_id, AcDb::kForRead, TDbCamera, pCam);
if (pCam == NULL) {
HideDialog(FALSE);
return;
}
nVP = pCam->GetAssociateViewport();
m_rectVP = GetVPRect(pCam->GetAssociateViewport());
OPENOBJ_END();
VERIFY(xg_setvar(_T("CVPORT"), nVP)==RTNORM);
if (m_rectVP.Width()>0 && m_rectVP.Width()<10000 &&
m_rectVP.Height()>0 && m_rectVP.Height()<10000) {
m_bHasInitAvi = TRUE;
CWnd *pParentWnd = acedGetAcadFrame();
if (pParentWnd != NULL) {
//避免对话框不见了,否则在此一直运行
m_fileAvi.SetSaveOptionsParentWnd(pParentWnd->m_hWnd);
}
else {
m_fileAvi.SetHasSaveOptionsDialog(FALSE);
}
m_fileAvi.SetColorNum(GetColorNum());
m_fileAvi.Init(csAviFile, m_rectVP.Width(), m_rectVP.Height(), m_nRate);
if (m_fileAvi.IsOK()) {
if (m_bRender) {
// 渲染初始设置
AvErrorCode retval;
static int sbInitialized = FALSE;
if (!sbInitialized) {
retval = av_loadlib();
if (retval != AvRetNorm) {
acdbFail(_T("Library initialization failed.\n"));
} else {
sbInitialized = TRUE;
}
}
static int bInitialized = FALSE;
if (!bInitialized) {
retval = av_initialize();
if (retval != AvRetNorm) {
acdbFail(_T("initialization failed.\n"));
} else {
bInitialized = TRUE;
}
}
SetSunLight(); //设置光源
SetMaterial(); //设置材质
//设置渲染配置
if (SetRenderConfig()) {
m_sTGAFile=GetTempFileName(_T(".tga"));
m_sBMPFile=GetTempFileName(_T(".bmp"));
if (m_sTGAFile && m_sBMPFile) {
//渲染和逐步制作动画
acedSetStatusBarProgressMeter(_T("正在制作动画,按ESC中断"), 0, m_nFrameNum);
for(int i = 0; i<m_nFrameNum && !ads_usrbrk() && m_fileAvi.IsOK(); i++) {
TakePhoto();
}
acedRestoreStatusBar();
//ads_command(RTSTR, _T("UNDO"), RTSTR, _T("1"), RTNONE);//出错
ads_command(RTSTR, _T("REGEN"), RTNONE);
}
}
}
else {
if (m_bIsPathCam){
OPENOBJ_BEGIN(m_ePathCam, AcDb::kForWrite, AcDbEntity, pEnt);
if (pEnt)
pEnt->setVisibility(AcDb::kInvisible);
OPENOBJ_END();
}
if (m_bIsPathTar) {
OPENOBJ_BEGIN(m_ePathTar, AcDb::kForWrite, AcDbEntity, pEnt);
if (pEnt)
pEnt->setVisibility(AcDb::kInvisible);
OPENOBJ_END();
}
acedSetStatusBarProgressMeter(_T("正在制作动画,按ESC中断"), 0, m_nFrameNum);
for(int i = 0; i<m_nFrameNum && !ads_usrbrk() && m_fileAvi.IsOK(); i++) {
TakePhoto();
}
acedRestoreStatusBar();
ads_command(RTSTR, _T("UNDO"), RTSTR, _T("1"), RTNONE);//出错
ads_command(RTSTR, _T("REGEN"), RTNONE);
}
}
}
CDialog::OnOK();
}
void CPathVideoDlg::TakePhoto()
{
XVector3D vtNormal(0,0,1);
XPoint ptCamera, ptTarget;
BOOL bOpend=FALSE;
OPENOBJ_BEGIN(m_id, AcDb::kForWrite, TDbCamera, pCam);
if (pCam != NULL) {
if (m_bIsPathCam) {
XPoint ptCamHead = *m_pathCamera.Head();
double nLenCam = m_pathCamera.Distance3d();
double nStemCam = nLenCam / m_nFrameNum;
m_pathCamera.Polar3d(nStemCam*m_nCount, ptCamera, vtNormal);
pCam->SetCamera(ptCamera);
}
else {
pCam->SetCamera(m_ptCamera); //拾取点
}
if (m_bIsPathTar) {
XPoint ptTarHead = *m_pathTarget.Head();
double nLenTar = m_pathTarget.Distance3d();
double nStepTar = nLenTar / m_nFrameNum;
m_pathTarget.Polar3d(nStepTar*m_nCount, ptTarget, vtNormal);
pCam->SetTarget(ptTarget);
}
else {
pCam->SetTarget(m_ptTarget);
}
//如果不是预览,即制作动画
if (m_bTakePhoto) {
pCam->SetActive(TRUE);
if (pCam->downgradeOpen()==Acad::eOk) {
pCam->draw();
pCam->TakePhoto((m_nCount!=0 && m_nCount!=m_nFrameNum && !m_bRender));
pCam->upgradeOpen();
bOpend = TRUE;
}
}
}
OPENOBJ_END();
//如果不是预览,则制作动画
if (m_bTakePhoto && bOpend) {
if (m_bRender && Render() && FindFile(m_sTGAFile)) {
if (FindFile(m_sBMPFile)) {
_tremove(m_sBMPFile);
}
CTexture texture;
if (texture.ReadFile(m_sTGAFile)) {
texture.SaveFile(m_sBMPFile);
if (FindFile(m_sBMPFile)) {
m_fileAvi.AddFrame(m_sBMPFile);
}
}
}
else {
CBitmap bitmap;
GetRectBmpFromBmp(acedGetAcadDwgView(), m_rectVP, bitmap);
m_fileAvi.AddFrame(bitmap);
}
acedSetStatusBarProgressMeterPos(m_nCount+1);
}
m_nCount++;
}
//渲染设置(CLineVideoDlg::SetRenderConfig())
BOOL CPathVideoDlg::SetRenderConfig()
{
AvErrorCode retval;
//渲染系统配置
AvRprefParam pRpref;
pRpref.mode = AvRprefSet; // 设置
pRpref.renderType = AvRprefRenderRaytrace; // 照片级光线跟踪渲染
pRpref.destination = AvRprefDestFile; // 文件
AvRprefToggleParam Toggle; // 渲染选项
Toggle.AvRprefSmoothToggle = TRUE; // 平滑着色
Toggle.AvRprefShadowToggle = TRUE; // 阴影 true
Toggle.AvRprefFinishToggle = TRUE;
Toggle.AvRprefMergeToggle = FALSE;
Toggle.AvRprefSkipRdlgToggle = TRUE; // 跳过渲染对话框
Toggle.AvRprefCropwindowToggle = FALSE; // 修剪窗口
Toggle.flags= AvRprefSmooth
| AvRprefShadow
| AvRprefFinish
| AvRprefMerge
| AvRprefSkipRdlg
| AvRprefCropwindow;
pRpref.toggle = Toggle;
pRpref.flags = AvRprefDestination
| AvRprefRenderType
| AvRprefToggle;
if ((retval = av_rpref(&pRpref)) != AvRetNorm) {
acutPrintf(_T("\n error: %s"), av_errorstr(retval));
return FALSE;
}
pRpref.mode = AvRprefRopt;
pRpref.antiAlias = AvRprefAntiAliasMedium;
pRpref.renderType = AvRprefRenderRaytrace;
pRpref.flags = AvRprefRenderType |
AvRprefAntiAlias;
if ((retval = av_rpref(&pRpref)) != AvRetNorm) {
acutPrintf(_T("\n error: %s"), av_errorstr(retval));
return FALSE;
}
//配置输出TGA文件参数
AvFileOptParam pTGAParam;
pTGAParam.mode = AvFileOptTGA;
pTGAParam.xRes = m_rectVP.Width();
pTGAParam.yRes = m_rectVP.Height();
pTGAParam.aspectRatio = 1.0;
pTGAParam.colorMode = AvFileOptColorModeC32;
pTGAParam.interlace = 1;
pTGAParam.compression = TRUE;
pTGAParam.bottomUp = FALSE;
pTGAParam.flags = AvFileOptXRes |
AvFileOptYRes |
AvFileOptAspectRatio |
AvFileOptColorMode |
AvFileOptInterlace |
AvFileOptCompression |
AvFileOptBottomUp;
if ((retval = av_rfileopt(&pTGAParam)) != AvRetNorm) {
acutPrintf(_T("\n error: %s"), av_errorstr(retval));
return FALSE;
}
return TRUE;
}
//渲染(CLineVideoDlg::Render())
BOOL CPathVideoDlg::Render()
{
if (!m_sTGAFile)
return FALSE;
if (!m_fileAvi.IsOK())
return FALSE;
if (FindFile(m_sTGAFile)) {
if (_tremove(m_sTGAFile) != 0)
return FALSE;
}
//渲染
AvErrorCode retval;
AvRenderParam pRenderParam;
pRenderParam.mode = AvRender; //不要对话框
pRenderParam.fileName = m_sTGAFile; //文件名
pRenderParam.flags = AvRenderFilename;
if ((retval = av_render(&pRenderParam)) != AvRetNorm) {
acutPrintf(_T("\n error: %s"), av_errorstr(retval));
return FALSE;
}
return TRUE;
}
void CPathVideoDlg::OnDestroy()
{
if (FindFile(m_sTGAFile)) {
_tremove(m_sTGAFile);
}
if (FindFile(m_sBMPFile)) {
_tremove(m_sBMPFile);
}
if (m_bInit) {
TDbCamera::ResetIdArray();
}
CDialog::OnDestroy();
}
UINT CPathVideoDlg::GetColorNum()
{
UINT nColorNum = 24;
UpdateData(TRUE);
switch(m_nColorNum) {
case 0:
nColorNum = 8;
break;
case 1:
nColorNum = 16;
break;
case 2:
nColorNum = 24;
break;
case 3:
nColorNum = 32;
break;
default:
break;
}
return nColorNum;
}
#endif/*ADS<17*/